mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-04 19:44:05 +00:00
Adopt various rust side Timeline API additions (#3423)
* Adopt new reaction toggling API introduced in matrix-org/matrix-rust-sdk/pull/4127 * Adopt the changes introduced in matrix-org/matrix-rust-sdk/pull/4111: use the new `TimelineUniqueId` type instead of `String` for unique timeline identifiers. * Bump the RustSDK to v1.0.58. * Fix unit tests
This commit is contained in:
@@ -7806,7 +7806,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.57;
|
version = 1.0.58;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = {
|
701C7BEF8F70F7A83E852DCC /* XCRemoteSwiftPackageReference "GZIP" */ = {
|
||||||
|
|||||||
@@ -149,8 +149,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" : "5f01589d44aa7045dc1ad87f2583f6083295d3eb",
|
"revision" : "753c5381ce88b3549cbd8ed9b839109ff143ecdd",
|
||||||
"version" : "1.0.57"
|
"version" : "1.0.58"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -933,7 +933,11 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
|||||||
MXLog.debug("Selected \(emoji) for \(itemID)")
|
MXLog.debug("Selected \(emoji) for \(itemID)")
|
||||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||||
Task {
|
Task {
|
||||||
await self.timelineController?.toggleReaction(emoji, to: itemID)
|
guard case let .event(_, eventOrTransactionID) = itemID else {
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
|
||||||
|
await self.timelineController?.toggleReaction(emoji, to: eventOrTransactionID)
|
||||||
}
|
}
|
||||||
case .dismiss:
|
case .dismiss:
|
||||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||||
|
|||||||
@@ -14057,8 +14057,8 @@ class TimelineProxyMock: TimelineProxyProtocol {
|
|||||||
var redactReasonCalled: Bool {
|
var redactReasonCalled: Bool {
|
||||||
return redactReasonCallsCount > 0
|
return redactReasonCallsCount > 0
|
||||||
}
|
}
|
||||||
var redactReasonReceivedArguments: (timelineItemID: TimelineItemIdentifier, reason: String?)?
|
var redactReasonReceivedArguments: (eventOrTransactionID: EventOrTransactionId, reason: String?)?
|
||||||
var redactReasonReceivedInvocations: [(timelineItemID: TimelineItemIdentifier, reason: String?)] = []
|
var redactReasonReceivedInvocations: [(eventOrTransactionID: EventOrTransactionId, reason: String?)] = []
|
||||||
|
|
||||||
var redactReasonUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
var redactReasonUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||||
var redactReasonReturnValue: Result<Void, TimelineProxyError>! {
|
var redactReasonReturnValue: Result<Void, TimelineProxyError>! {
|
||||||
@@ -14084,16 +14084,16 @@ class TimelineProxyMock: TimelineProxyProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var redactReasonClosure: ((TimelineItemIdentifier, String?) async -> Result<Void, TimelineProxyError>)?
|
var redactReasonClosure: ((EventOrTransactionId, String?) async -> Result<Void, TimelineProxyError>)?
|
||||||
|
|
||||||
func redact(_ timelineItemID: TimelineItemIdentifier, reason: String?) async -> Result<Void, TimelineProxyError> {
|
func redact(_ eventOrTransactionID: EventOrTransactionId, reason: String?) async -> Result<Void, TimelineProxyError> {
|
||||||
redactReasonCallsCount += 1
|
redactReasonCallsCount += 1
|
||||||
redactReasonReceivedArguments = (timelineItemID: timelineItemID, reason: reason)
|
redactReasonReceivedArguments = (eventOrTransactionID: eventOrTransactionID, reason: reason)
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.redactReasonReceivedInvocations.append((timelineItemID: timelineItemID, reason: reason))
|
self.redactReasonReceivedInvocations.append((eventOrTransactionID: eventOrTransactionID, reason: reason))
|
||||||
}
|
}
|
||||||
if let redactReasonClosure = redactReasonClosure {
|
if let redactReasonClosure = redactReasonClosure {
|
||||||
return await redactReasonClosure(timelineItemID, reason)
|
return await redactReasonClosure(eventOrTransactionID, reason)
|
||||||
} else {
|
} else {
|
||||||
return redactReasonReturnValue
|
return redactReasonReturnValue
|
||||||
}
|
}
|
||||||
@@ -14867,8 +14867,8 @@ class TimelineProxyMock: TimelineProxyProtocol {
|
|||||||
var toggleReactionToCalled: Bool {
|
var toggleReactionToCalled: Bool {
|
||||||
return toggleReactionToCallsCount > 0
|
return toggleReactionToCallsCount > 0
|
||||||
}
|
}
|
||||||
var toggleReactionToReceivedArguments: (reaction: String, itemID: TimelineItemIdentifier)?
|
var toggleReactionToReceivedArguments: (reaction: String, eventID: EventOrTransactionId)?
|
||||||
var toggleReactionToReceivedInvocations: [(reaction: String, itemID: TimelineItemIdentifier)] = []
|
var toggleReactionToReceivedInvocations: [(reaction: String, eventID: EventOrTransactionId)] = []
|
||||||
|
|
||||||
var toggleReactionToUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
var toggleReactionToUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||||
var toggleReactionToReturnValue: Result<Void, TimelineProxyError>! {
|
var toggleReactionToReturnValue: Result<Void, TimelineProxyError>! {
|
||||||
@@ -14894,16 +14894,16 @@ class TimelineProxyMock: TimelineProxyProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var toggleReactionToClosure: ((String, TimelineItemIdentifier) async -> Result<Void, TimelineProxyError>)?
|
var toggleReactionToClosure: ((String, EventOrTransactionId) async -> Result<Void, TimelineProxyError>)?
|
||||||
|
|
||||||
func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async -> Result<Void, TimelineProxyError> {
|
func toggleReaction(_ reaction: String, to eventID: EventOrTransactionId) async -> Result<Void, TimelineProxyError> {
|
||||||
toggleReactionToCallsCount += 1
|
toggleReactionToCallsCount += 1
|
||||||
toggleReactionToReceivedArguments = (reaction: reaction, itemID: itemID)
|
toggleReactionToReceivedArguments = (reaction: reaction, eventID: eventID)
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.toggleReactionToReceivedInvocations.append((reaction: reaction, itemID: itemID))
|
self.toggleReactionToReceivedInvocations.append((reaction: reaction, eventID: eventID))
|
||||||
}
|
}
|
||||||
if let toggleReactionToClosure = toggleReactionToClosure {
|
if let toggleReactionToClosure = toggleReactionToClosure {
|
||||||
return await toggleReactionToClosure(reaction, itemID)
|
return await toggleReactionToClosure(reaction, eventID)
|
||||||
} else {
|
} else {
|
||||||
return toggleReactionToReturnValue
|
return toggleReactionToReturnValue
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,17 +15,17 @@ open class ClientSDKMock: MatrixRustSDK.Client {
|
|||||||
|
|
||||||
fileprivate var pointer: UnsafeMutableRawPointer!
|
fileprivate var pointer: UnsafeMutableRawPointer!
|
||||||
|
|
||||||
//MARK: - abortOidcLogin
|
//MARK: - abortOidcAuth
|
||||||
|
|
||||||
var abortOidcLoginAuthorizationDataUnderlyingCallsCount = 0
|
var abortOidcAuthAuthorizationDataUnderlyingCallsCount = 0
|
||||||
open var abortOidcLoginAuthorizationDataCallsCount: Int {
|
open var abortOidcAuthAuthorizationDataCallsCount: Int {
|
||||||
get {
|
get {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
return abortOidcLoginAuthorizationDataUnderlyingCallsCount
|
return abortOidcAuthAuthorizationDataUnderlyingCallsCount
|
||||||
} else {
|
} else {
|
||||||
var returnValue: Int? = nil
|
var returnValue: Int? = nil
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
returnValue = abortOidcLoginAuthorizationDataUnderlyingCallsCount
|
returnValue = abortOidcAuthAuthorizationDataUnderlyingCallsCount
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnValue!
|
return returnValue!
|
||||||
@@ -33,28 +33,28 @@ open class ClientSDKMock: MatrixRustSDK.Client {
|
|||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
abortOidcLoginAuthorizationDataUnderlyingCallsCount = newValue
|
abortOidcAuthAuthorizationDataUnderlyingCallsCount = newValue
|
||||||
} else {
|
} else {
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
abortOidcLoginAuthorizationDataUnderlyingCallsCount = newValue
|
abortOidcAuthAuthorizationDataUnderlyingCallsCount = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
open var abortOidcLoginAuthorizationDataCalled: Bool {
|
open var abortOidcAuthAuthorizationDataCalled: Bool {
|
||||||
return abortOidcLoginAuthorizationDataCallsCount > 0
|
return abortOidcAuthAuthorizationDataCallsCount > 0
|
||||||
}
|
}
|
||||||
open var abortOidcLoginAuthorizationDataReceivedAuthorizationData: OidcAuthorizationData?
|
open var abortOidcAuthAuthorizationDataReceivedAuthorizationData: OidcAuthorizationData?
|
||||||
open var abortOidcLoginAuthorizationDataReceivedInvocations: [OidcAuthorizationData] = []
|
open var abortOidcAuthAuthorizationDataReceivedInvocations: [OidcAuthorizationData] = []
|
||||||
open var abortOidcLoginAuthorizationDataClosure: ((OidcAuthorizationData) async -> Void)?
|
open var abortOidcAuthAuthorizationDataClosure: ((OidcAuthorizationData) async -> Void)?
|
||||||
|
|
||||||
open override func abortOidcLogin(authorizationData: OidcAuthorizationData) async {
|
open override func abortOidcAuth(authorizationData: OidcAuthorizationData) async {
|
||||||
abortOidcLoginAuthorizationDataCallsCount += 1
|
abortOidcAuthAuthorizationDataCallsCount += 1
|
||||||
abortOidcLoginAuthorizationDataReceivedAuthorizationData = authorizationData
|
abortOidcAuthAuthorizationDataReceivedAuthorizationData = authorizationData
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.abortOidcLoginAuthorizationDataReceivedInvocations.append(authorizationData)
|
self.abortOidcAuthAuthorizationDataReceivedInvocations.append(authorizationData)
|
||||||
}
|
}
|
||||||
await abortOidcLoginAuthorizationDataClosure?(authorizationData)
|
await abortOidcAuthAuthorizationDataClosure?(authorizationData)
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - accountData
|
//MARK: - accountData
|
||||||
@@ -3872,18 +3872,18 @@ open class ClientSDKMock: MatrixRustSDK.Client {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - urlForOidcLogin
|
//MARK: - urlForOidc
|
||||||
|
|
||||||
open var urlForOidcLoginOidcConfigurationThrowableError: Error?
|
open var urlForOidcOidcConfigurationPromptThrowableError: Error?
|
||||||
var urlForOidcLoginOidcConfigurationUnderlyingCallsCount = 0
|
var urlForOidcOidcConfigurationPromptUnderlyingCallsCount = 0
|
||||||
open var urlForOidcLoginOidcConfigurationCallsCount: Int {
|
open var urlForOidcOidcConfigurationPromptCallsCount: Int {
|
||||||
get {
|
get {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
return urlForOidcLoginOidcConfigurationUnderlyingCallsCount
|
return urlForOidcOidcConfigurationPromptUnderlyingCallsCount
|
||||||
} else {
|
} else {
|
||||||
var returnValue: Int? = nil
|
var returnValue: Int? = nil
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
returnValue = urlForOidcLoginOidcConfigurationUnderlyingCallsCount
|
returnValue = urlForOidcOidcConfigurationPromptUnderlyingCallsCount
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnValue!
|
return returnValue!
|
||||||
@@ -3891,29 +3891,29 @@ open class ClientSDKMock: MatrixRustSDK.Client {
|
|||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
urlForOidcLoginOidcConfigurationUnderlyingCallsCount = newValue
|
urlForOidcOidcConfigurationPromptUnderlyingCallsCount = newValue
|
||||||
} else {
|
} else {
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
urlForOidcLoginOidcConfigurationUnderlyingCallsCount = newValue
|
urlForOidcOidcConfigurationPromptUnderlyingCallsCount = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
open var urlForOidcLoginOidcConfigurationCalled: Bool {
|
open var urlForOidcOidcConfigurationPromptCalled: Bool {
|
||||||
return urlForOidcLoginOidcConfigurationCallsCount > 0
|
return urlForOidcOidcConfigurationPromptCallsCount > 0
|
||||||
}
|
}
|
||||||
open var urlForOidcLoginOidcConfigurationReceivedOidcConfiguration: OidcConfiguration?
|
open var urlForOidcOidcConfigurationPromptReceivedArguments: (oidcConfiguration: OidcConfiguration, prompt: OidcPrompt)?
|
||||||
open var urlForOidcLoginOidcConfigurationReceivedInvocations: [OidcConfiguration] = []
|
open var urlForOidcOidcConfigurationPromptReceivedInvocations: [(oidcConfiguration: OidcConfiguration, prompt: OidcPrompt)] = []
|
||||||
|
|
||||||
var urlForOidcLoginOidcConfigurationUnderlyingReturnValue: OidcAuthorizationData!
|
var urlForOidcOidcConfigurationPromptUnderlyingReturnValue: OidcAuthorizationData!
|
||||||
open var urlForOidcLoginOidcConfigurationReturnValue: OidcAuthorizationData! {
|
open var urlForOidcOidcConfigurationPromptReturnValue: OidcAuthorizationData! {
|
||||||
get {
|
get {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
return urlForOidcLoginOidcConfigurationUnderlyingReturnValue
|
return urlForOidcOidcConfigurationPromptUnderlyingReturnValue
|
||||||
} else {
|
} else {
|
||||||
var returnValue: OidcAuthorizationData? = nil
|
var returnValue: OidcAuthorizationData? = nil
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
returnValue = urlForOidcLoginOidcConfigurationUnderlyingReturnValue
|
returnValue = urlForOidcOidcConfigurationPromptUnderlyingReturnValue
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnValue!
|
return returnValue!
|
||||||
@@ -3921,29 +3921,29 @@ open class ClientSDKMock: MatrixRustSDK.Client {
|
|||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
urlForOidcLoginOidcConfigurationUnderlyingReturnValue = newValue
|
urlForOidcOidcConfigurationPromptUnderlyingReturnValue = newValue
|
||||||
} else {
|
} else {
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
urlForOidcLoginOidcConfigurationUnderlyingReturnValue = newValue
|
urlForOidcOidcConfigurationPromptUnderlyingReturnValue = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
open var urlForOidcLoginOidcConfigurationClosure: ((OidcConfiguration) async throws -> OidcAuthorizationData)?
|
open var urlForOidcOidcConfigurationPromptClosure: ((OidcConfiguration, OidcPrompt) async throws -> OidcAuthorizationData)?
|
||||||
|
|
||||||
open override func urlForOidcLogin(oidcConfiguration: OidcConfiguration) async throws -> OidcAuthorizationData {
|
open override func urlForOidc(oidcConfiguration: OidcConfiguration, prompt: OidcPrompt) async throws -> OidcAuthorizationData {
|
||||||
if let error = urlForOidcLoginOidcConfigurationThrowableError {
|
if let error = urlForOidcOidcConfigurationPromptThrowableError {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
urlForOidcLoginOidcConfigurationCallsCount += 1
|
urlForOidcOidcConfigurationPromptCallsCount += 1
|
||||||
urlForOidcLoginOidcConfigurationReceivedOidcConfiguration = oidcConfiguration
|
urlForOidcOidcConfigurationPromptReceivedArguments = (oidcConfiguration: oidcConfiguration, prompt: prompt)
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.urlForOidcLoginOidcConfigurationReceivedInvocations.append(oidcConfiguration)
|
self.urlForOidcOidcConfigurationPromptReceivedInvocations.append((oidcConfiguration: oidcConfiguration, prompt: prompt))
|
||||||
}
|
}
|
||||||
if let urlForOidcLoginOidcConfigurationClosure = urlForOidcLoginOidcConfigurationClosure {
|
if let urlForOidcOidcConfigurationPromptClosure = urlForOidcOidcConfigurationPromptClosure {
|
||||||
return try await urlForOidcLoginOidcConfigurationClosure(oidcConfiguration)
|
return try await urlForOidcOidcConfigurationPromptClosure(oidcConfiguration, prompt)
|
||||||
} else {
|
} else {
|
||||||
return urlForOidcLoginOidcConfigurationReturnValue
|
return urlForOidcOidcConfigurationPromptReturnValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -19484,16 +19484,16 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline {
|
|||||||
|
|
||||||
//MARK: - toggleReaction
|
//MARK: - toggleReaction
|
||||||
|
|
||||||
open var toggleReactionUniqueIdKeyThrowableError: Error?
|
open var toggleReactionItemIdKeyThrowableError: Error?
|
||||||
var toggleReactionUniqueIdKeyUnderlyingCallsCount = 0
|
var toggleReactionItemIdKeyUnderlyingCallsCount = 0
|
||||||
open var toggleReactionUniqueIdKeyCallsCount: Int {
|
open var toggleReactionItemIdKeyCallsCount: Int {
|
||||||
get {
|
get {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
return toggleReactionUniqueIdKeyUnderlyingCallsCount
|
return toggleReactionItemIdKeyUnderlyingCallsCount
|
||||||
} else {
|
} else {
|
||||||
var returnValue: Int? = nil
|
var returnValue: Int? = nil
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
returnValue = toggleReactionUniqueIdKeyUnderlyingCallsCount
|
returnValue = toggleReactionItemIdKeyUnderlyingCallsCount
|
||||||
}
|
}
|
||||||
|
|
||||||
return returnValue!
|
return returnValue!
|
||||||
@@ -19501,31 +19501,31 @@ open class TimelineSDKMock: MatrixRustSDK.Timeline {
|
|||||||
}
|
}
|
||||||
set {
|
set {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
toggleReactionUniqueIdKeyUnderlyingCallsCount = newValue
|
toggleReactionItemIdKeyUnderlyingCallsCount = newValue
|
||||||
} else {
|
} else {
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
toggleReactionUniqueIdKeyUnderlyingCallsCount = newValue
|
toggleReactionItemIdKeyUnderlyingCallsCount = newValue
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
open var toggleReactionUniqueIdKeyCalled: Bool {
|
open var toggleReactionItemIdKeyCalled: Bool {
|
||||||
return toggleReactionUniqueIdKeyCallsCount > 0
|
return toggleReactionItemIdKeyCallsCount > 0
|
||||||
}
|
}
|
||||||
open var toggleReactionUniqueIdKeyReceivedArguments: (uniqueId: String, key: String)?
|
open var toggleReactionItemIdKeyReceivedArguments: (itemId: EventOrTransactionId, key: String)?
|
||||||
open var toggleReactionUniqueIdKeyReceivedInvocations: [(uniqueId: String, key: String)] = []
|
open var toggleReactionItemIdKeyReceivedInvocations: [(itemId: EventOrTransactionId, key: String)] = []
|
||||||
open var toggleReactionUniqueIdKeyClosure: ((String, String) async throws -> Void)?
|
open var toggleReactionItemIdKeyClosure: ((EventOrTransactionId, String) async throws -> Void)?
|
||||||
|
|
||||||
open override func toggleReaction(uniqueId: String, key: String) async throws {
|
open override func toggleReaction(itemId: EventOrTransactionId, key: String) async throws {
|
||||||
if let error = toggleReactionUniqueIdKeyThrowableError {
|
if let error = toggleReactionItemIdKeyThrowableError {
|
||||||
throw error
|
throw error
|
||||||
}
|
}
|
||||||
toggleReactionUniqueIdKeyCallsCount += 1
|
toggleReactionItemIdKeyCallsCount += 1
|
||||||
toggleReactionUniqueIdKeyReceivedArguments = (uniqueId: uniqueId, key: key)
|
toggleReactionItemIdKeyReceivedArguments = (itemId: itemId, key: key)
|
||||||
DispatchQueue.main.async {
|
DispatchQueue.main.async {
|
||||||
self.toggleReactionUniqueIdKeyReceivedInvocations.append((uniqueId: uniqueId, key: key))
|
self.toggleReactionItemIdKeyReceivedInvocations.append((itemId: itemId, key: key))
|
||||||
}
|
}
|
||||||
try await toggleReactionUniqueIdKeyClosure?(uniqueId, key)
|
try await toggleReactionItemIdKeyClosure?(itemId, key)
|
||||||
}
|
}
|
||||||
|
|
||||||
//MARK: - unpinEvent
|
//MARK: - unpinEvent
|
||||||
@@ -20724,13 +20724,13 @@ open class TimelineItemSDKMock: MatrixRustSDK.TimelineItem {
|
|||||||
return uniqueIdCallsCount > 0
|
return uniqueIdCallsCount > 0
|
||||||
}
|
}
|
||||||
|
|
||||||
var uniqueIdUnderlyingReturnValue: String!
|
var uniqueIdUnderlyingReturnValue: TimelineUniqueId!
|
||||||
open var uniqueIdReturnValue: String! {
|
open var uniqueIdReturnValue: TimelineUniqueId! {
|
||||||
get {
|
get {
|
||||||
if Thread.isMainThread {
|
if Thread.isMainThread {
|
||||||
return uniqueIdUnderlyingReturnValue
|
return uniqueIdUnderlyingReturnValue
|
||||||
} else {
|
} else {
|
||||||
var returnValue: String? = nil
|
var returnValue: TimelineUniqueId? = nil
|
||||||
DispatchQueue.main.sync {
|
DispatchQueue.main.sync {
|
||||||
returnValue = uniqueIdUnderlyingReturnValue
|
returnValue = uniqueIdUnderlyingReturnValue
|
||||||
}
|
}
|
||||||
@@ -20748,9 +20748,9 @@ open class TimelineItemSDKMock: MatrixRustSDK.TimelineItem {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
open var uniqueIdClosure: (() -> String)?
|
open var uniqueIdClosure: (() -> TimelineUniqueId)?
|
||||||
|
|
||||||
open override func uniqueId() -> String {
|
open override func uniqueId() -> TimelineUniqueId {
|
||||||
uniqueIdCallsCount += 1
|
uniqueIdCallsCount += 1
|
||||||
if let uniqueIdClosure = uniqueIdClosure {
|
if let uniqueIdClosure = uniqueIdClosure {
|
||||||
return uniqueIdClosure()
|
return uniqueIdClosure()
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ class AutoUpdatingRoomTimelineProviderMock: RoomTimelineProvider {
|
|||||||
|
|
||||||
let timelineItem = TimelineItemSDKMock()
|
let timelineItem = TimelineItemSDKMock()
|
||||||
timelineItem.asEventReturnValue = EventTimelineItem.mockMessage
|
timelineItem.asEventReturnValue = EventTimelineItem.mockMessage
|
||||||
timelineItem.uniqueIdReturnValue = UUID().uuidString
|
timelineItem.uniqueIdReturnValue = .init(id: UUID().uuidString)
|
||||||
|
|
||||||
diff.appendReturnValue = [timelineItem]
|
diff.appendReturnValue = [timelineItem]
|
||||||
|
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ extension ClientSDKMock {
|
|||||||
userIdServerNameThrowableError = MockError.generic
|
userIdServerNameThrowableError = MockError.generic
|
||||||
serverReturnValue = "https://\(configuration.serverAddress)"
|
serverReturnValue = "https://\(configuration.serverAddress)"
|
||||||
getUrlUrlReturnValue = configuration.elementWellKnown
|
getUrlUrlReturnValue = configuration.elementWellKnown
|
||||||
urlForOidcLoginOidcConfigurationReturnValue = OidcAuthorizationDataSDKMock(configuration: configuration)
|
urlForOidcOidcConfigurationPromptReturnValue = OidcAuthorizationDataSDKMock(configuration: configuration)
|
||||||
loginUsernamePasswordInitialDeviceNameDeviceIdClosure = { username, password, _, _ in
|
loginUsernamePasswordInitialDeviceNameDeviceIdClosure = { username, password, _, _ in
|
||||||
guard username == configuration.validCredentials.username,
|
guard username == configuration.validCredentials.username,
|
||||||
password == configuration.validCredentials.password else {
|
password == configuration.validCredentials.password else {
|
||||||
|
|||||||
@@ -132,8 +132,12 @@ class TimelineInteractionHandler {
|
|||||||
UIPasteboard.general.url = permalinkURL
|
UIPasteboard.general.url = permalinkURL
|
||||||
}
|
}
|
||||||
case .redact:
|
case .redact:
|
||||||
|
guard case let .event(_, eventOrTransactionID) = itemID else {
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
|
||||||
Task {
|
Task {
|
||||||
await timelineController.redact(itemID)
|
await timelineController.redact(eventOrTransactionID)
|
||||||
}
|
}
|
||||||
case .reply:
|
case .reply:
|
||||||
guard let eventID = eventTimelineItem.id.eventID else {
|
guard let eventID = eventTimelineItem.id.eventID else {
|
||||||
@@ -159,7 +163,13 @@ class TimelineInteractionHandler {
|
|||||||
case .react:
|
case .react:
|
||||||
displayEmojiPicker(for: itemID)
|
displayEmojiPicker(for: itemID)
|
||||||
case .toggleReaction(let key):
|
case .toggleReaction(let key):
|
||||||
Task { await timelineController.toggleReaction(key, to: itemID) }
|
Task {
|
||||||
|
guard case let .event(_, eventOrTransactionID) = itemID else {
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
|
||||||
|
await timelineController.toggleReaction(key, to: eventOrTransactionID)
|
||||||
|
}
|
||||||
case .endPoll(let pollStartID):
|
case .endPoll(let pollStartID):
|
||||||
endPoll(pollStartID: pollStartID)
|
endPoll(pollStartID: pollStartID)
|
||||||
case .pin:
|
case .pin:
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Combine
|
import Combine
|
||||||
|
import MatrixRustSDK
|
||||||
import OrderedCollections
|
import OrderedCollections
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
@@ -202,9 +203,9 @@ struct TimelineState {
|
|||||||
// These can be removed when we have full swiftUI and moved as @State values in the view
|
// These can be removed when we have full swiftUI and moved as @State values in the view
|
||||||
var scrollToBottomPublisher = PassthroughSubject<Void, Never>()
|
var scrollToBottomPublisher = PassthroughSubject<Void, Never>()
|
||||||
|
|
||||||
var itemsDictionary = OrderedDictionary<String, RoomTimelineItemViewState>()
|
var itemsDictionary = OrderedDictionary<TimelineUniqueId, RoomTimelineItemViewState>()
|
||||||
|
|
||||||
var uniqueIDs: [String] {
|
var uniqueIDs: [TimelineUniqueId] {
|
||||||
itemsDictionary.keys.elements
|
itemsDictionary.keys.elements
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
|
|
||||||
import Combine
|
import Combine
|
||||||
import Compound
|
import Compound
|
||||||
|
import MatrixRustSDK
|
||||||
import SwiftUI
|
import SwiftUI
|
||||||
|
|
||||||
import OrderedCollections
|
import OrderedCollections
|
||||||
@@ -47,7 +48,7 @@ class TimelineTableViewController: UIViewController {
|
|||||||
private let coordinator: TimelineView.Coordinator
|
private let coordinator: TimelineView.Coordinator
|
||||||
private let tableView = UITableView(frame: .zero, style: .plain)
|
private let tableView = UITableView(frame: .zero, style: .plain)
|
||||||
|
|
||||||
var timelineItemsDictionary = OrderedDictionary<String, RoomTimelineItemViewState>() {
|
var timelineItemsDictionary = OrderedDictionary<TimelineUniqueId, RoomTimelineItemViewState>() {
|
||||||
didSet {
|
didSet {
|
||||||
guard canApplySnapshot else {
|
guard canApplySnapshot else {
|
||||||
hasPendingItems = true
|
hasPendingItems = true
|
||||||
@@ -145,12 +146,12 @@ class TimelineTableViewController: UIViewController {
|
|||||||
|
|
||||||
@Binding private var isScrolledToBottom: Bool
|
@Binding private var isScrolledToBottom: Bool
|
||||||
|
|
||||||
private var timelineItemsIDs: [String] {
|
private var timelineItemsIDs: [TimelineUniqueId] {
|
||||||
timelineItemsDictionary.keys.elements.reversed()
|
timelineItemsDictionary.keys.elements.reversed()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The table's diffable data source.
|
/// The table's diffable data source.
|
||||||
private var dataSource: UITableViewDiffableDataSource<TimelineSection, String>?
|
private var dataSource: UITableViewDiffableDataSource<TimelineSection, TimelineUniqueId>?
|
||||||
private var cancellables = Set<AnyCancellable>()
|
private var cancellables = Set<AnyCancellable>()
|
||||||
|
|
||||||
/// A publisher used to throttle back pagination requests.
|
/// A publisher used to throttle back pagination requests.
|
||||||
@@ -246,7 +247,7 @@ class TimelineTableViewController: UIViewController {
|
|||||||
private func configureDataSource() {
|
private func configureDataSource() {
|
||||||
dataSource = .init(tableView: tableView) { [weak self] tableView, indexPath, id in
|
dataSource = .init(tableView: tableView) { [weak self] tableView, indexPath, id in
|
||||||
switch id {
|
switch id {
|
||||||
case TimelineTypingIndicatorCell.reuseIdentifier:
|
case TimelineUniqueId(id: TimelineTypingIndicatorCell.reuseIdentifier):
|
||||||
let cell = tableView.dequeueReusableCell(withIdentifier: TimelineTypingIndicatorCell.reuseIdentifier, for: indexPath)
|
let cell = tableView.dequeueReusableCell(withIdentifier: TimelineTypingIndicatorCell.reuseIdentifier, for: indexPath)
|
||||||
guard let self else {
|
guard let self else {
|
||||||
return cell
|
return cell
|
||||||
@@ -312,12 +313,12 @@ class TimelineTableViewController: UIViewController {
|
|||||||
private func applySnapshot() {
|
private func applySnapshot() {
|
||||||
guard let dataSource else { return }
|
guard let dataSource else { return }
|
||||||
|
|
||||||
var snapshot = NSDiffableDataSourceSnapshot<TimelineSection, String>()
|
var snapshot = NSDiffableDataSourceSnapshot<TimelineSection, TimelineUniqueId>()
|
||||||
|
|
||||||
// We don't want to display the typing notification in this timeline
|
// We don't want to display the typing notification in this timeline
|
||||||
if !coordinator.context.viewState.isPinnedEventsTimeline {
|
if !coordinator.context.viewState.isPinnedEventsTimeline {
|
||||||
snapshot.appendSections([.typingIndicator])
|
snapshot.appendSections([.typingIndicator])
|
||||||
snapshot.appendItems([TimelineTypingIndicatorCell.reuseIdentifier])
|
snapshot.appendItems([TimelineUniqueId(id: TimelineTypingIndicatorCell.reuseIdentifier)])
|
||||||
}
|
}
|
||||||
snapshot.appendSections([.main])
|
snapshot.appendSections([.main])
|
||||||
snapshot.appendItems(timelineItemsIDs)
|
snapshot.appendItems(timelineItemsIDs)
|
||||||
@@ -516,7 +517,7 @@ extension TimelineTableViewController {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Returns the frame of the cell for a particular timeline item.
|
/// Returns the frame of the cell for a particular timeline item.
|
||||||
private func cellFrame(for uniqueID: String) -> CGRect? {
|
private func cellFrame(for uniqueID: TimelineUniqueId) -> CGRect? {
|
||||||
guard let timelineCell = tableView.visibleCells.first(where: { ($0 as? TimelineItemCell)?.item?.identifier.uniqueID == uniqueID }) else {
|
guard let timelineCell = tableView.visibleCells.first(where: { ($0 as? TimelineItemCell)?.item?.identifier.uniqueID == uniqueID }) else {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
@@ -536,13 +537,13 @@ extension TimelineTableViewController {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension NSDiffableDataSourceSnapshot<TimelineTableViewController.TimelineSection, String> {
|
private extension NSDiffableDataSourceSnapshot<TimelineTableViewController.TimelineSection, TimelineUniqueId> {
|
||||||
var numberOfMainItems: Int {
|
var numberOfMainItems: Int {
|
||||||
guard sectionIdentifiers.contains(.main) else { return 0 }
|
guard sectionIdentifiers.contains(.main) else { return 0 }
|
||||||
return numberOfItems(inSection: .main)
|
return numberOfItems(inSection: .main)
|
||||||
}
|
}
|
||||||
|
|
||||||
var mainItemIdentifiers: [String] {
|
var mainItemIdentifiers: [TimelineUniqueId] {
|
||||||
guard sectionIdentifiers.contains(.main) else { return [] }
|
guard sectionIdentifiers.contains(.main) else { return [] }
|
||||||
return itemIdentifiers(inSection: .main)
|
return itemIdentifiers(inSection: .main)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -131,8 +131,12 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
|||||||
Task { await handleItemTapped(with: id) }
|
Task { await handleItemTapped(with: id) }
|
||||||
case .itemSendInfoTapped(let itemID):
|
case .itemSendInfoTapped(let itemID):
|
||||||
handleItemSendInfoTapped(itemID: itemID)
|
handleItemSendInfoTapped(itemID: itemID)
|
||||||
case .toggleReaction(let emoji, let itemId):
|
case .toggleReaction(let emoji, let itemID):
|
||||||
Task { await timelineController.toggleReaction(emoji, to: itemId) }
|
guard case let .event(_, eventOrTransactionID) = itemID else {
|
||||||
|
fatalError()
|
||||||
|
}
|
||||||
|
|
||||||
|
Task { await timelineController.toggleReaction(emoji, to: eventOrTransactionID) }
|
||||||
case .sendReadReceiptIfNeeded(let lastVisibleItemID):
|
case .sendReadReceiptIfNeeded(let lastVisibleItemID):
|
||||||
Task { await sendReadReceiptIfNeeded(for: lastVisibleItemID) }
|
Task { await sendReadReceiptIfNeeded(for: lastVisibleItemID) }
|
||||||
case .paginateBackwards:
|
case .paginateBackwards:
|
||||||
@@ -639,7 +643,7 @@ class TimelineViewModel: TimelineViewModelType, TimelineViewModelProtocol {
|
|||||||
// MARK: - Timeline Item Building
|
// MARK: - Timeline Item Building
|
||||||
|
|
||||||
private func buildTimelineViews(timelineItems: [RoomTimelineItemProtocol], isSwitchingTimelines: Bool = false) {
|
private func buildTimelineViews(timelineItems: [RoomTimelineItemProtocol], isSwitchingTimelines: Bool = false) {
|
||||||
var timelineItemsDictionary = OrderedDictionary<String, RoomTimelineItemViewState>()
|
var timelineItemsDictionary = OrderedDictionary<TimelineUniqueId, RoomTimelineItemViewState>()
|
||||||
|
|
||||||
timelineItems.filter { $0 is RedactedRoomTimelineItem }.forEach { timelineItem in
|
timelineItems.filter { $0 is RedactedRoomTimelineItem }.forEach { timelineItem in
|
||||||
// Stops the audio player when a voice message is redacted.
|
// Stops the audio player when a voice message is redacted.
|
||||||
|
|||||||
@@ -623,7 +623,7 @@ private struct MockTimelineContent: View {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func makeItemIdentifier() -> TimelineItemIdentifier {
|
func makeItemIdentifier() -> TimelineItemIdentifier {
|
||||||
isPinned ? .event(uniqueID: "", eventOrTransactionID: .eventId(eventId: "pinned")) : .randomEvent
|
isPinned ? .event(uniqueID: .init(id: ""), eventOrTransactionID: .eventId(eventId: "pinned")) : .randomEvent
|
||||||
}
|
}
|
||||||
|
|
||||||
var replyDetails: TimelineItemReplyDetails? {
|
var replyDetails: TimelineItemReplyDetails? {
|
||||||
|
|||||||
@@ -79,7 +79,7 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
static let sendingLast: TextRoomTimelineItem = {
|
static let sendingLast: TextRoomTimelineItem = {
|
||||||
let id = viewModel.state.timelineViewState.uniqueIDs.last ?? UUID().uuidString
|
let id = viewModel.state.timelineViewState.uniqueIDs.last ?? .init(id: UUID().uuidString)
|
||||||
var result = TextRoomTimelineItem(id: .event(uniqueID: id, eventOrTransactionID: .eventId(eventId: UUID().uuidString)),
|
var result = TextRoomTimelineItem(id: .event(uniqueID: id, eventOrTransactionID: .eventId(eventId: UUID().uuidString)),
|
||||||
timestamp: "Now",
|
timestamp: "Now",
|
||||||
isOutgoing: true,
|
isOutgoing: true,
|
||||||
@@ -99,7 +99,7 @@ struct TimelineItemStyler_Previews: PreviewProvider, TestablePreview {
|
|||||||
}()
|
}()
|
||||||
|
|
||||||
static let sentLast: TextRoomTimelineItem = {
|
static let sentLast: TextRoomTimelineItem = {
|
||||||
let id = viewModel.state.timelineViewState.uniqueIDs.last ?? UUID().uuidString
|
let id = viewModel.state.timelineViewState.uniqueIDs.last ?? .init(id: UUID().uuidString)
|
||||||
let result = TextRoomTimelineItem(id: .event(uniqueID: id, eventOrTransactionID: .eventId(eventId: UUID().uuidString)),
|
let result = TextRoomTimelineItem(id: .event(uniqueID: id, eventOrTransactionID: .eventId(eventId: UUID().uuidString)),
|
||||||
timestamp: "Now",
|
timestamp: "Now",
|
||||||
isOutgoing: true,
|
isOutgoing: true,
|
||||||
|
|||||||
+2
-2
@@ -52,8 +52,8 @@ struct CollapsibleRoomTimelineView: View {
|
|||||||
|
|
||||||
struct CollapsibleRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
struct CollapsibleRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
||||||
static let item = CollapsibleTimelineItem(items: [
|
static let item = CollapsibleTimelineItem(items: [
|
||||||
SeparatorRoomTimelineItem(id: .virtual(uniqueID: "First separator"), text: "This is a separator"),
|
SeparatorRoomTimelineItem(id: .virtual(uniqueID: .init(id: "First separator")), text: "This is a separator"),
|
||||||
SeparatorRoomTimelineItem(id: .virtual(uniqueID: "Second separator"), text: "This is another separator")
|
SeparatorRoomTimelineItem(id: .virtual(uniqueID: .init(id: "Second separator")), text: "This is another separator")
|
||||||
])
|
])
|
||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
|
|||||||
+2
-2
@@ -33,7 +33,7 @@ struct ReadMarkerRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
|||||||
|
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
VStack(alignment: .leading, spacing: 0) {
|
VStack(alignment: .leading, spacing: 0) {
|
||||||
RoomTimelineItemView(viewState: .init(type: .separator(.init(id: .virtual(uniqueID: "Separator"), text: "Today")), groupStyle: .single))
|
RoomTimelineItemView(viewState: .init(type: .separator(.init(id: .virtual(uniqueID: .init(id: "Separator")), text: "Today")), groupStyle: .single))
|
||||||
RoomTimelineItemView(viewState: .init(type: .text(.init(id: .randomEvent,
|
RoomTimelineItemView(viewState: .init(type: .text(.init(id: .randomEvent,
|
||||||
timestamp: "",
|
timestamp: "",
|
||||||
isOutgoing: true,
|
isOutgoing: true,
|
||||||
@@ -45,7 +45,7 @@ struct ReadMarkerRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
|||||||
|
|
||||||
ReadMarkerRoomTimelineView(timelineItem: item)
|
ReadMarkerRoomTimelineView(timelineItem: item)
|
||||||
|
|
||||||
RoomTimelineItemView(viewState: .init(type: .separator(.init(id: .virtual(uniqueID: "Separator"), text: "Today")), groupStyle: .single))
|
RoomTimelineItemView(viewState: .init(type: .separator(.init(id: .virtual(uniqueID: .init(id: "Separator")), text: "Today")), groupStyle: .single))
|
||||||
RoomTimelineItemView(viewState: .init(type: .text(.init(id: .randomEvent,
|
RoomTimelineItemView(viewState: .init(type: .text(.init(id: .randomEvent,
|
||||||
timestamp: "",
|
timestamp: "",
|
||||||
isOutgoing: false,
|
isOutgoing: false,
|
||||||
|
|||||||
+1
-1
@@ -23,7 +23,7 @@ struct SeparatorRoomTimelineView: View {
|
|||||||
|
|
||||||
struct SeparatorRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
struct SeparatorRoomTimelineView_Previews: PreviewProvider, TestablePreview {
|
||||||
static var previews: some View {
|
static var previews: some View {
|
||||||
let item = SeparatorRoomTimelineItem(id: .virtual(uniqueID: "Separator"),
|
let item = SeparatorRoomTimelineItem(id: .virtual(uniqueID: .init(id: "Separator")),
|
||||||
text: "This is a separator")
|
text: "This is a separator")
|
||||||
SeparatorRoomTimelineView(timelineItem: item)
|
SeparatorRoomTimelineView(timelineItem: item)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,7 +91,7 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
|||||||
func urlForOIDCLogin() async -> Result<OIDCAuthorizationDataProxy, AuthenticationServiceError> {
|
func urlForOIDCLogin() async -> Result<OIDCAuthorizationDataProxy, AuthenticationServiceError> {
|
||||||
guard let client else { return .failure(.oidcError(.urlFailure)) }
|
guard let client else { return .failure(.oidcError(.urlFailure)) }
|
||||||
do {
|
do {
|
||||||
let oidcData = try await client.urlForOidcLogin(oidcConfiguration: appSettings.oidcConfiguration.rustValue)
|
let oidcData = try await client.urlForOidc(oidcConfiguration: appSettings.oidcConfiguration.rustValue, prompt: .consent)
|
||||||
return .success(OIDCAuthorizationDataProxy(underlyingData: oidcData))
|
return .success(OIDCAuthorizationDataProxy(underlyingData: oidcData))
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed to get URL for OIDC login: \(error)")
|
MXLog.error("Failed to get URL for OIDC login: \(error)")
|
||||||
@@ -102,7 +102,7 @@ class AuthenticationService: AuthenticationServiceProtocol {
|
|||||||
func abortOIDCLogin(data: OIDCAuthorizationDataProxy) async {
|
func abortOIDCLogin(data: OIDCAuthorizationDataProxy) async {
|
||||||
guard let client else { return }
|
guard let client else { return }
|
||||||
MXLog.info("Aborting OIDC login.")
|
MXLog.info("Aborting OIDC login.")
|
||||||
await client.abortOidcLogin(authorizationData: data.underlyingData)
|
await client.abortOidcAuth(authorizationData: data.underlyingData)
|
||||||
}
|
}
|
||||||
|
|
||||||
func loginWithOIDCCallback(_ callbackURL: URL, data: OIDCAuthorizationDataProxy) async -> Result<UserSessionProtocol, AuthenticationServiceError> {
|
func loginWithOIDCCallback(_ callbackURL: URL, data: OIDCAuthorizationDataProxy) async -> Result<UserSessionProtocol, AuthenticationServiceError> {
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ class RoomSummaryProvider: RoomSummaryProviderProtocol {
|
|||||||
var lastMessageFormattedTimestamp: String?
|
var lastMessageFormattedTimestamp: String?
|
||||||
|
|
||||||
if let latestRoomMessage = roomDetails.latestEvent {
|
if let latestRoomMessage = roomDetails.latestEvent {
|
||||||
let lastMessage = EventTimelineItemProxy(item: latestRoomMessage, uniqueID: "0")
|
let lastMessage = EventTimelineItemProxy(item: latestRoomMessage, uniqueID: .init(id: "0"))
|
||||||
lastMessageFormattedTimestamp = lastMessage.timestamp.formattedMinimal()
|
lastMessageFormattedTimestamp = lastMessage.timestamp.formattedMinimal()
|
||||||
attributedLastMessage = eventStringBuilder.buildAttributedString(for: lastMessage)
|
attributedLastMessage = eventStringBuilder.buildAttributedString(for: lastMessage)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,8 +10,8 @@ import Foundation
|
|||||||
enum RoomTimelineItemFixtures {
|
enum RoomTimelineItemFixtures {
|
||||||
/// The default timeline items used in Xcode previews etc.
|
/// The default timeline items used in Xcode previews etc.
|
||||||
static var `default`: [RoomTimelineItemProtocol] = [
|
static var `default`: [RoomTimelineItemProtocol] = [
|
||||||
SeparatorRoomTimelineItem(id: .virtual(uniqueID: "Yesterday"), text: "Yesterday"),
|
SeparatorRoomTimelineItem(id: .virtual(uniqueID: .init(id: "Yesterday")), text: "Yesterday"),
|
||||||
TextRoomTimelineItem(id: .event(uniqueID: ".RoomTimelineItemFixtures.default.0",
|
TextRoomTimelineItem(id: .event(uniqueID: .init(id: ".RoomTimelineItemFixtures.default.0"),
|
||||||
eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.0")),
|
eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.0")),
|
||||||
timestamp: "10:10 AM",
|
timestamp: "10:10 AM",
|
||||||
isOutgoing: false,
|
isOutgoing: false,
|
||||||
@@ -21,7 +21,7 @@ enum RoomTimelineItemFixtures {
|
|||||||
sender: .init(id: "", displayName: "Jacob"),
|
sender: .init(id: "", displayName: "Jacob"),
|
||||||
content: .init(body: "That looks so good!"),
|
content: .init(body: "That looks so good!"),
|
||||||
properties: RoomTimelineItemProperties(isEdited: true)),
|
properties: RoomTimelineItemProperties(isEdited: true)),
|
||||||
TextRoomTimelineItem(id: .event(uniqueID: "RoomTimelineItemFixtures.default.1",
|
TextRoomTimelineItem(id: .event(uniqueID: .init(id: "RoomTimelineItemFixtures.default.1"),
|
||||||
eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.1")),
|
eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.1")),
|
||||||
timestamp: "10:11 AM",
|
timestamp: "10:11 AM",
|
||||||
isOutgoing: false,
|
isOutgoing: false,
|
||||||
@@ -33,7 +33,7 @@ enum RoomTimelineItemFixtures {
|
|||||||
properties: RoomTimelineItemProperties(reactions: [
|
properties: RoomTimelineItemProperties(reactions: [
|
||||||
AggregatedReaction(accountOwnerID: "me", key: "🙌", senders: [ReactionSender(id: "me", timestamp: Date())])
|
AggregatedReaction(accountOwnerID: "me", key: "🙌", senders: [ReactionSender(id: "me", timestamp: Date())])
|
||||||
])),
|
])),
|
||||||
TextRoomTimelineItem(id: .event(uniqueID: "RoomTimelineItemFixtures.default.2",
|
TextRoomTimelineItem(id: .event(uniqueID: .init(id: "RoomTimelineItemFixtures.default.2"),
|
||||||
eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.2")),
|
eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.2")),
|
||||||
timestamp: "10:11 AM",
|
timestamp: "10:11 AM",
|
||||||
isOutgoing: false,
|
isOutgoing: false,
|
||||||
@@ -52,8 +52,8 @@ enum RoomTimelineItemFixtures {
|
|||||||
ReactionSender(id: "jacob", timestamp: Date())
|
ReactionSender(id: "jacob", timestamp: Date())
|
||||||
])
|
])
|
||||||
])),
|
])),
|
||||||
SeparatorRoomTimelineItem(id: .virtual(uniqueID: "Today"), text: "Today"),
|
SeparatorRoomTimelineItem(id: .virtual(uniqueID: .init(id: "Today")), text: "Today"),
|
||||||
TextRoomTimelineItem(id: .event(uniqueID: "RoomTimelineItemFixtures.default.3",
|
TextRoomTimelineItem(id: .event(uniqueID: .init(id: "RoomTimelineItemFixtures.default.3"),
|
||||||
eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.3")),
|
eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.3")),
|
||||||
timestamp: "5 PM",
|
timestamp: "5 PM",
|
||||||
isOutgoing: false,
|
isOutgoing: false,
|
||||||
@@ -63,7 +63,7 @@ enum RoomTimelineItemFixtures {
|
|||||||
sender: .init(id: "", displayName: "Helena"),
|
sender: .init(id: "", displayName: "Helena"),
|
||||||
content: .init(body: "Wow, cool. Ok, lets go the usual place tomorrow?! Is that too soon? Here’s the menu, let me know what you want it’s on me!"),
|
content: .init(body: "Wow, cool. Ok, lets go the usual place tomorrow?! Is that too soon? Here’s the menu, let me know what you want it’s on me!"),
|
||||||
properties: RoomTimelineItemProperties(orderedReadReceipts: [ReadReceipt(userID: "alice", formattedTimestamp: nil)])),
|
properties: RoomTimelineItemProperties(orderedReadReceipts: [ReadReceipt(userID: "alice", formattedTimestamp: nil)])),
|
||||||
TextRoomTimelineItem(id: .event(uniqueID: "RoomTimelineItemFixtures.default.4",
|
TextRoomTimelineItem(id: .event(uniqueID: .init(id: "RoomTimelineItemFixtures.default.4"),
|
||||||
eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.4")),
|
eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.4")),
|
||||||
timestamp: "5 PM",
|
timestamp: "5 PM",
|
||||||
isOutgoing: true,
|
isOutgoing: true,
|
||||||
@@ -72,7 +72,7 @@ enum RoomTimelineItemFixtures {
|
|||||||
isThreaded: false,
|
isThreaded: false,
|
||||||
sender: .init(id: "", displayName: "Bob"),
|
sender: .init(id: "", displayName: "Bob"),
|
||||||
content: .init(body: "And John's speech was amazing!")),
|
content: .init(body: "And John's speech was amazing!")),
|
||||||
TextRoomTimelineItem(id: .event(uniqueID: "RoomTimelineItemFixtures.default.5",
|
TextRoomTimelineItem(id: .event(uniqueID: .init(id: "RoomTimelineItemFixtures.default.5"),
|
||||||
eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.5")),
|
eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.5")),
|
||||||
timestamp: "5 PM",
|
timestamp: "5 PM",
|
||||||
isOutgoing: true,
|
isOutgoing: true,
|
||||||
@@ -86,7 +86,7 @@ enum RoomTimelineItemFixtures {
|
|||||||
ReadReceipt(userID: "bob", formattedTimestamp: nil),
|
ReadReceipt(userID: "bob", formattedTimestamp: nil),
|
||||||
ReadReceipt(userID: "charlie", formattedTimestamp: nil),
|
ReadReceipt(userID: "charlie", formattedTimestamp: nil),
|
||||||
ReadReceipt(userID: "dan", formattedTimestamp: nil)])),
|
ReadReceipt(userID: "dan", formattedTimestamp: nil)])),
|
||||||
TextRoomTimelineItem(id: .event(uniqueID: "RoomTimelineItemFixtures.default.6",
|
TextRoomTimelineItem(id: .event(uniqueID: .init(id: "RoomTimelineItemFixtures.default.6"),
|
||||||
eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.6")),
|
eventOrTransactionID: .eventId(eventId: "RoomTimelineItemFixtures.default.6")),
|
||||||
timestamp: "5 PM",
|
timestamp: "5 PM",
|
||||||
isOutgoing: false,
|
isOutgoing: false,
|
||||||
@@ -242,7 +242,7 @@ enum RoomTimelineItemFixtures {
|
|||||||
|
|
||||||
static var permalinkChunk: [RoomTimelineItemProtocol] {
|
static var permalinkChunk: [RoomTimelineItemProtocol] {
|
||||||
(1...20).map { index in
|
(1...20).map { index in
|
||||||
TextRoomTimelineItem(id: .event(uniqueID: "\(index)", eventOrTransactionID: .eventId(eventId: "$\(index)")),
|
TextRoomTimelineItem(id: .event(uniqueID: .init(id: "\(index)"), eventOrTransactionID: .eventId(eventId: "$\(index)")),
|
||||||
text: "Message ID \(index)",
|
text: "Message ID \(index)",
|
||||||
senderDisplayName: index > 10 ? "Alice" : "Bob")
|
senderDisplayName: index > 10 ? "Alice" : "Bob")
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -84,7 +84,7 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
|
|||||||
inReplyToEventID: String?,
|
inReplyToEventID: String?,
|
||||||
intentionalMentions: IntentionalMentions) async { }
|
intentionalMentions: IntentionalMentions) async { }
|
||||||
|
|
||||||
func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async { }
|
func toggleReaction(_ reaction: String, to eventID: EventOrTransactionId) async { }
|
||||||
|
|
||||||
func edit(_ eventOrTransactionID: EventOrTransactionId,
|
func edit(_ eventOrTransactionID: EventOrTransactionId,
|
||||||
useTimeline: Bool,
|
useTimeline: Bool,
|
||||||
@@ -92,7 +92,7 @@ class MockRoomTimelineController: RoomTimelineControllerProtocol {
|
|||||||
html: String?,
|
html: String?,
|
||||||
intentionalMentions: IntentionalMentions) async { }
|
intentionalMentions: IntentionalMentions) async { }
|
||||||
|
|
||||||
func redact(_ itemID: TimelineItemIdentifier) async { }
|
func redact(_ eventOrTransactionID: EventOrTransactionId) async { }
|
||||||
|
|
||||||
func pin(eventID: String) async { }
|
func pin(eventID: String) async { }
|
||||||
|
|
||||||
|
|||||||
@@ -158,10 +158,10 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async {
|
func toggleReaction(_ reaction: String, to eventOrTransactionID: EventOrTransactionId) async {
|
||||||
MXLog.info("Toggle reaction in \(roomID)")
|
MXLog.info("Toggle reaction \(reaction) to \(eventOrTransactionID)")
|
||||||
|
|
||||||
switch await activeTimeline.toggleReaction(reaction, to: itemID) {
|
switch await activeTimeline.toggleReaction(reaction, to: eventOrTransactionID) {
|
||||||
case .success:
|
case .success:
|
||||||
MXLog.info("Finished toggling reaction")
|
MXLog.info("Finished toggling reaction")
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
@@ -203,10 +203,10 @@ class RoomTimelineController: RoomTimelineControllerProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func redact(_ timelineItemID: TimelineItemIdentifier) async {
|
func redact(_ eventOrTransactionID: EventOrTransactionId) async {
|
||||||
MXLog.info("Send redaction in \(roomID)")
|
MXLog.info("Send redaction in \(roomID)")
|
||||||
|
|
||||||
switch await activeTimeline.redact(timelineItemID, reason: nil) {
|
switch await activeTimeline.redact(eventOrTransactionID, reason: nil) {
|
||||||
case .success:
|
case .success:
|
||||||
MXLog.info("Finished redacting message")
|
MXLog.info("Finished redacting message")
|
||||||
case .failure(let error):
|
case .failure(let error):
|
||||||
|
|||||||
+2
-2
@@ -57,9 +57,9 @@ protocol RoomTimelineControllerProtocol {
|
|||||||
html: String?,
|
html: String?,
|
||||||
intentionalMentions: IntentionalMentions) async
|
intentionalMentions: IntentionalMentions) async
|
||||||
|
|
||||||
func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async
|
func toggleReaction(_ reaction: String, to eventOrTransactionID: EventOrTransactionId) async
|
||||||
|
|
||||||
func redact(_ itemID: TimelineItemIdentifier) async
|
func redact(_ eventOrTransactionID: EventOrTransactionId) async
|
||||||
|
|
||||||
func pin(eventID: String) async
|
func pin(eventID: String) async
|
||||||
|
|
||||||
|
|||||||
@@ -14,10 +14,10 @@ import MatrixRustSDK
|
|||||||
/// - eventOrTransactionID: Contains the 2 possible identifiers of an event, either it has a remote event id or
|
/// - eventOrTransactionID: Contains the 2 possible identifiers of an event, either it has a remote event id or
|
||||||
/// a local transaction id, never both or none.
|
/// a local transaction id, never both or none.
|
||||||
enum TimelineItemIdentifier: Hashable {
|
enum TimelineItemIdentifier: Hashable {
|
||||||
case event(uniqueID: String, eventOrTransactionID: EventOrTransactionId)
|
case event(uniqueID: TimelineUniqueId, eventOrTransactionID: EventOrTransactionId)
|
||||||
case virtual(uniqueID: String)
|
case virtual(uniqueID: TimelineUniqueId)
|
||||||
|
|
||||||
var uniqueID: String {
|
var uniqueID: TimelineUniqueId {
|
||||||
switch self {
|
switch self {
|
||||||
case .event(let uniqueID, _):
|
case .event(let uniqueID, _):
|
||||||
return uniqueID
|
return uniqueID
|
||||||
@@ -57,10 +57,10 @@ enum TimelineItemIdentifier: Hashable {
|
|||||||
|
|
||||||
extension TimelineItemIdentifier {
|
extension TimelineItemIdentifier {
|
||||||
static var randomEvent: Self {
|
static var randomEvent: Self {
|
||||||
.event(uniqueID: UUID().uuidString, eventOrTransactionID: .eventId(eventId: UUID().uuidString))
|
.event(uniqueID: .init(id: UUID().uuidString), eventOrTransactionID: .eventId(eventId: UUID().uuidString))
|
||||||
}
|
}
|
||||||
|
|
||||||
static var randomVirtual: Self {
|
static var randomVirtual: Self {
|
||||||
.virtual(uniqueID: UUID().uuidString)
|
.virtual(uniqueID: .init(id: UUID().uuidString))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,14 +11,14 @@ import MatrixRustSDK
|
|||||||
/// A light wrapper around timeline items returned from Rust.
|
/// A light wrapper around timeline items returned from Rust.
|
||||||
enum TimelineItemProxy {
|
enum TimelineItemProxy {
|
||||||
case event(EventTimelineItemProxy)
|
case event(EventTimelineItemProxy)
|
||||||
case virtual(MatrixRustSDK.VirtualTimelineItem, uniqueID: String)
|
case virtual(MatrixRustSDK.VirtualTimelineItem, uniqueID: TimelineUniqueId)
|
||||||
case unknown(MatrixRustSDK.TimelineItem)
|
case unknown(MatrixRustSDK.TimelineItem)
|
||||||
|
|
||||||
init(item: MatrixRustSDK.TimelineItem) {
|
init(item: MatrixRustSDK.TimelineItem) {
|
||||||
if let eventItem = item.asEvent() {
|
if let eventItem = item.asEvent() {
|
||||||
self = .event(EventTimelineItemProxy(item: eventItem, uniqueID: String(item.uniqueId())))
|
self = .event(EventTimelineItemProxy(item: eventItem, uniqueID: item.uniqueId()))
|
||||||
} else if let virtualItem = item.asVirtual() {
|
} else if let virtualItem = item.asVirtual() {
|
||||||
self = .virtual(virtualItem, uniqueID: String(item.uniqueId()))
|
self = .virtual(virtualItem, uniqueID: item.uniqueId())
|
||||||
} else {
|
} else {
|
||||||
self = .unknown(item)
|
self = .unknown(item)
|
||||||
}
|
}
|
||||||
@@ -71,7 +71,7 @@ class EventTimelineItemProxy {
|
|||||||
let item: MatrixRustSDK.EventTimelineItem
|
let item: MatrixRustSDK.EventTimelineItem
|
||||||
let id: TimelineItemIdentifier
|
let id: TimelineItemIdentifier
|
||||||
|
|
||||||
init(item: MatrixRustSDK.EventTimelineItem, uniqueID: String) {
|
init(item: MatrixRustSDK.EventTimelineItem, uniqueID: TimelineUniqueId) {
|
||||||
self.item = item
|
self.item = item
|
||||||
|
|
||||||
id = .event(uniqueID: uniqueID, eventOrTransactionID: item.eventOrTransactionId)
|
id = .event(uniqueID: uniqueID, eventOrTransactionID: item.eventOrTransactionId)
|
||||||
|
|||||||
+1
-1
@@ -22,6 +22,6 @@ struct PaginationIndicatorRoomTimelineItem: DecorationTimelineItemProtocol, Equa
|
|||||||
}
|
}
|
||||||
|
|
||||||
init(position: Position) {
|
init(position: Position) {
|
||||||
id = .virtual(uniqueID: position.id)
|
id = .virtual(uniqueID: .init(id: position.id))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -8,6 +8,6 @@
|
|||||||
import Foundation
|
import Foundation
|
||||||
|
|
||||||
struct TimelineStartRoomTimelineItem: DecorationTimelineItemProtocol, Equatable {
|
struct TimelineStartRoomTimelineItem: DecorationTimelineItemProtocol, Equatable {
|
||||||
let id: TimelineItemIdentifier = .virtual(uniqueID: UUID().uuidString)
|
let id: TimelineItemIdentifier = .virtual(uniqueID: .init(id: UUID().uuidString))
|
||||||
let name: String?
|
let name: String?
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
import Foundation
|
import Foundation
|
||||||
|
import MatrixRustSDK
|
||||||
|
|
||||||
final class RoomTimelineItemViewState: Identifiable, Equatable, ObservableObject {
|
final class RoomTimelineItemViewState: Identifiable, Equatable, ObservableObject {
|
||||||
@Published var type: RoomTimelineItemType
|
@Published var type: RoomTimelineItemType
|
||||||
@@ -34,7 +35,7 @@ final class RoomTimelineItemViewState: Identifiable, Equatable, ObservableObject
|
|||||||
// MARK: Identifiable
|
// MARK: Identifiable
|
||||||
|
|
||||||
/// The `timelineID` of the item, used for the timeline view level identification, do not use for any business logic use `identifier` instead
|
/// The `timelineID` of the item, used for the timeline view level identification, do not use for any business logic use `identifier` instead
|
||||||
var id: String {
|
var id: TimelineUniqueId {
|
||||||
identifier.uniqueID
|
identifier.uniqueID
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -179,22 +179,17 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func redact(_ timelineItemID: TimelineItemIdentifier, reason: String?) async -> Result<Void, TimelineProxyError> {
|
func redact(_ eventOrTransactionID: EventOrTransactionId, reason: String?) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.info("Redacting timeline item: \(timelineItemID)")
|
MXLog.info("Redacting timeline item: \(eventOrTransactionID)")
|
||||||
|
|
||||||
guard let eventOrTransactionID = await timelineProvider.itemProxies.firstEventTimelineItemUsingStableID(timelineItemID)?.eventOrTransactionId else {
|
|
||||||
MXLog.error("Unknown timeline item: \(timelineItemID)")
|
|
||||||
return .failure(.failedRedacting)
|
|
||||||
}
|
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try await timeline.redactEvent(eventOrTransactionId: eventOrTransactionID, reason: reason)
|
try await timeline.redactEvent(eventOrTransactionId: eventOrTransactionID, reason: reason)
|
||||||
|
|
||||||
MXLog.info("Redacted timeline item: \(timelineItemID)")
|
MXLog.info("Redacted timeline item: \(eventOrTransactionID)")
|
||||||
|
|
||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed redacting timeline item: \(timelineItemID) with error: \(error)")
|
MXLog.error("Failed redacting timeline item: \(eventOrTransactionID) with error: \(error)")
|
||||||
return .failure(.sdkError(error))
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -426,15 +421,15 @@ final class TimelineProxy: TimelineProxyProtocol {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async -> Result<Void, TimelineProxyError> {
|
func toggleReaction(_ reaction: String, to eventOrTransactionID: EventOrTransactionId) async -> Result<Void, TimelineProxyError> {
|
||||||
MXLog.info("Toggling reaction for event: \(itemID)")
|
MXLog.info("Toggling reaction \(reaction) for event: \(eventOrTransactionID)")
|
||||||
|
|
||||||
do {
|
do {
|
||||||
try await timeline.toggleReaction(uniqueId: itemID.uniqueID, key: reaction)
|
try await timeline.toggleReaction(itemId: eventOrTransactionID, key: reaction)
|
||||||
MXLog.info("Finished toggling reaction for event: \(itemID)")
|
MXLog.info("Finished toggling reaction for event: \(eventOrTransactionID)")
|
||||||
return .success(())
|
return .success(())
|
||||||
} catch {
|
} catch {
|
||||||
MXLog.error("Failed toggling reaction for event: \(itemID)")
|
MXLog.error("Failed toggling reaction for event: \(eventOrTransactionID)")
|
||||||
return .failure(.sdkError(error))
|
return .failure(.sdkError(error))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ protocol TimelineProxyProtocol {
|
|||||||
func edit(_ eventOrTransactionID: EventOrTransactionId,
|
func edit(_ eventOrTransactionID: EventOrTransactionId,
|
||||||
newContent: RoomMessageEventContentWithoutRelation) async -> Result<Void, TimelineProxyError>
|
newContent: RoomMessageEventContentWithoutRelation) async -> Result<Void, TimelineProxyError>
|
||||||
|
|
||||||
func redact(_ timelineItemID: TimelineItemIdentifier,
|
func redact(_ eventOrTransactionID: EventOrTransactionId,
|
||||||
reason: String?) async -> Result<Void, TimelineProxyError>
|
reason: String?) async -> Result<Void, TimelineProxyError>
|
||||||
|
|
||||||
func pin(eventID: String) async -> Result<Bool, TimelineProxyError>
|
func pin(eventID: String) async -> Result<Bool, TimelineProxyError>
|
||||||
@@ -93,7 +93,7 @@ protocol TimelineProxyProtocol {
|
|||||||
inReplyToEventID: String?,
|
inReplyToEventID: String?,
|
||||||
intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError>
|
intentionalMentions: IntentionalMentions) async -> Result<Void, TimelineProxyError>
|
||||||
|
|
||||||
func toggleReaction(_ reaction: String, to itemID: TimelineItemIdentifier) async -> Result<Void, TimelineProxyError>
|
func toggleReaction(_ reaction: String, to eventID: EventOrTransactionId) async -> Result<Void, TimelineProxyError>
|
||||||
|
|
||||||
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>
|
||||||
|
|
||||||
|
|||||||
@@ -195,25 +195,25 @@ class LoggingTests: XCTestCase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let content = try String(contentsOf: logFile)
|
let content = try String(contentsOf: logFile)
|
||||||
XCTAssertTrue(content.contains(textMessage.id.uniqueID))
|
XCTAssertTrue(content.contains(textMessage.id.uniqueID.id))
|
||||||
XCTAssertFalse(content.contains(textMessage.body))
|
XCTAssertFalse(content.contains(textMessage.body))
|
||||||
XCTAssertFalse(content.contains(textAttributedString))
|
XCTAssertFalse(content.contains(textAttributedString))
|
||||||
|
|
||||||
XCTAssertTrue(content.contains(noticeMessage.id.uniqueID))
|
XCTAssertTrue(content.contains(noticeMessage.id.uniqueID.id))
|
||||||
XCTAssertFalse(content.contains(noticeMessage.body))
|
XCTAssertFalse(content.contains(noticeMessage.body))
|
||||||
XCTAssertFalse(content.contains(noticeAttributedString))
|
XCTAssertFalse(content.contains(noticeAttributedString))
|
||||||
|
|
||||||
XCTAssertTrue(content.contains(emoteMessage.id.uniqueID))
|
XCTAssertTrue(content.contains(emoteMessage.id.uniqueID.id))
|
||||||
XCTAssertFalse(content.contains(emoteMessage.body))
|
XCTAssertFalse(content.contains(emoteMessage.body))
|
||||||
XCTAssertFalse(content.contains(emoteAttributedString))
|
XCTAssertFalse(content.contains(emoteAttributedString))
|
||||||
|
|
||||||
XCTAssertTrue(content.contains(imageMessage.id.uniqueID))
|
XCTAssertTrue(content.contains(imageMessage.id.uniqueID.id))
|
||||||
XCTAssertFalse(content.contains(imageMessage.body))
|
XCTAssertFalse(content.contains(imageMessage.body))
|
||||||
|
|
||||||
XCTAssertTrue(content.contains(videoMessage.id.uniqueID))
|
XCTAssertTrue(content.contains(videoMessage.id.uniqueID.id))
|
||||||
XCTAssertFalse(content.contains(videoMessage.body))
|
XCTAssertFalse(content.contains(videoMessage.body))
|
||||||
|
|
||||||
XCTAssertTrue(content.contains(fileMessage.id.uniqueID))
|
XCTAssertTrue(content.contains(fileMessage.id.uniqueID.id))
|
||||||
XCTAssertFalse(content.contains(fileMessage.body))
|
XCTAssertFalse(content.contains(fileMessage.body))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ import XCTest
|
|||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
class MessageForwardingScreenViewModelTests: XCTestCase {
|
class MessageForwardingScreenViewModelTests: XCTestCase {
|
||||||
let forwardingItem = MessageForwardingItem(id: .event(uniqueID: "t1", eventOrTransactionID: .eventId(eventId: "t1")),
|
let forwardingItem = MessageForwardingItem(id: .event(uniqueID: .init(id: "t1"), eventOrTransactionID: .eventId(eventId: "t1")),
|
||||||
roomID: "1",
|
roomID: "1",
|
||||||
content: .init(noPointer: .init()))
|
content: .init(noPointer: .init()))
|
||||||
var viewModel: MessageForwardingScreenViewModelProtocol!
|
var viewModel: MessageForwardingScreenViewModelProtocol!
|
||||||
|
|||||||
@@ -69,8 +69,8 @@ class RoomScreenViewModelTests: XCTestCase {
|
|||||||
let providerUpdateSubject = PassthroughSubject<([TimelineItemProxy], PaginationState), Never>()
|
let providerUpdateSubject = PassthroughSubject<([TimelineItemProxy], PaginationState), Never>()
|
||||||
pinnedTimelineProviderMock.underlyingUpdatePublisher = providerUpdateSubject.eraseToAnyPublisher()
|
pinnedTimelineProviderMock.underlyingUpdatePublisher = providerUpdateSubject.eraseToAnyPublisher()
|
||||||
pinnedTimelineMock.timelineProvider = pinnedTimelineProviderMock
|
pinnedTimelineMock.timelineProvider = pinnedTimelineProviderMock
|
||||||
pinnedTimelineProviderMock.itemProxies = [.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: "1")),
|
pinnedTimelineProviderMock.itemProxies = [.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: .init(id: "1"))),
|
||||||
.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test2")), uniqueID: "2"))]
|
.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test2")), uniqueID: .init(id: "2")))]
|
||||||
|
|
||||||
// check if the banner is now in a loaded state and is showing the counter
|
// check if the banner is now in a loaded state and is showing the counter
|
||||||
deferred = deferFulfillment(viewModel.context.$viewState) { viewState in
|
deferred = deferFulfillment(viewModel.context.$viewState) { viewState in
|
||||||
@@ -86,9 +86,9 @@ class RoomScreenViewModelTests: XCTestCase {
|
|||||||
deferred = deferFulfillment(viewModel.context.$viewState) { viewState in
|
deferred = deferFulfillment(viewModel.context.$viewState) { viewState in
|
||||||
viewState.pinnedEventsBannerState.count == 3
|
viewState.pinnedEventsBannerState.count == 3
|
||||||
}
|
}
|
||||||
providerUpdateSubject.send(([.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: "1")),
|
providerUpdateSubject.send(([.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: .init(id: "1"))),
|
||||||
.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test2")), uniqueID: "2")),
|
.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test2")), uniqueID: .init(id: "2"))),
|
||||||
.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test3")), uniqueID: "3"))], .initial))
|
.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test3")), uniqueID: .init(id: "3")))], .initial))
|
||||||
try await deferred.fulfill()
|
try await deferred.fulfill()
|
||||||
XCTAssertFalse(viewModel.context.viewState.pinnedEventsBannerState.isLoading)
|
XCTAssertFalse(viewModel.context.viewState.pinnedEventsBannerState.isLoading)
|
||||||
XCTAssertTrue(viewModel.context.viewState.shouldShowPinnedEventsBanner)
|
XCTAssertTrue(viewModel.context.viewState.shouldShowPinnedEventsBanner)
|
||||||
@@ -109,9 +109,9 @@ class RoomScreenViewModelTests: XCTestCase {
|
|||||||
let pinnedTimelineProviderMock = RoomTimelineProviderMock()
|
let pinnedTimelineProviderMock = RoomTimelineProviderMock()
|
||||||
pinnedTimelineMock.timelineProvider = pinnedTimelineProviderMock
|
pinnedTimelineMock.timelineProvider = pinnedTimelineProviderMock
|
||||||
pinnedTimelineProviderMock.underlyingUpdatePublisher = Empty<([TimelineItemProxy], PaginationState), Never>().eraseToAnyPublisher()
|
pinnedTimelineProviderMock.underlyingUpdatePublisher = Empty<([TimelineItemProxy], PaginationState), Never>().eraseToAnyPublisher()
|
||||||
pinnedTimelineProviderMock.itemProxies = [.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: "1")),
|
pinnedTimelineProviderMock.itemProxies = [.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test1")), uniqueID: .init(id: "1"))),
|
||||||
.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test2")), uniqueID: "2")),
|
.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test2")), uniqueID: .init(id: "2"))),
|
||||||
.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test3")), uniqueID: "3"))]
|
.event(.init(item: EventTimelineItem(configuration: .init(eventID: "test3")), uniqueID: .init(id: "3")))]
|
||||||
roomProxyMock.underlyingPinnedEventsTimeline = pinnedTimelineMock
|
roomProxyMock.underlyingPinnedEventsTimeline = pinnedTimelineMock
|
||||||
let viewModel = RoomScreenViewModel(clientProxy: ClientProxyMock(),
|
let viewModel = RoomScreenViewModel(clientProxy: ClientProxyMock(),
|
||||||
roomProxy: roomProxyMock,
|
roomProxy: roomProxyMock,
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ class TimelineItemFactoryTests: XCTestCase {
|
|||||||
|
|
||||||
let eventTimelineItem = EventTimelineItem.mockCallInvite(sender: senderUserID)
|
let eventTimelineItem = EventTimelineItem.mockCallInvite(sender: senderUserID)
|
||||||
|
|
||||||
let eventTimelineItemProxy = EventTimelineItemProxy(item: eventTimelineItem, uniqueID: "0")
|
let eventTimelineItemProxy = EventTimelineItemProxy(item: eventTimelineItem, uniqueID: .init(id: "0"))
|
||||||
|
|
||||||
let item = factory.buildTimelineItem(for: eventTimelineItemProxy, isDM: false)
|
let item = factory.buildTimelineItem(for: eventTimelineItemProxy, isDM: false)
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@
|
|||||||
@testable import ElementX
|
@testable import ElementX
|
||||||
|
|
||||||
import Combine
|
import Combine
|
||||||
|
import MatrixRustSDK
|
||||||
import XCTest
|
import XCTest
|
||||||
|
|
||||||
@MainActor
|
@MainActor
|
||||||
@@ -258,9 +259,9 @@ class TimelineViewModelTests: XCTestCase {
|
|||||||
|
|
||||||
func testSendReadReceiptWithoutEvents() async throws {
|
func testSendReadReceiptWithoutEvents() async throws {
|
||||||
// Given a room with only virtual items.
|
// Given a room with only virtual items.
|
||||||
let items = [SeparatorRoomTimelineItem(uniqueID: "v1"),
|
let items = [SeparatorRoomTimelineItem(uniqueID: .init(id: "v1")),
|
||||||
SeparatorRoomTimelineItem(uniqueID: "v2"),
|
SeparatorRoomTimelineItem(uniqueID: .init(id: "v2")),
|
||||||
SeparatorRoomTimelineItem(uniqueID: "v3")]
|
SeparatorRoomTimelineItem(uniqueID: .init(id: "v3"))]
|
||||||
let (viewModel, _, timelineProxy, _) = readReceiptsConfiguration(with: items)
|
let (viewModel, _, timelineProxy, _) = readReceiptsConfiguration(with: items)
|
||||||
|
|
||||||
// When sending a read receipt for the last item.
|
// When sending a read receipt for the last item.
|
||||||
@@ -275,7 +276,7 @@ class TimelineViewModelTests: XCTestCase {
|
|||||||
// Given a room where the last event is a virtual item.
|
// Given a room where the last event is a virtual item.
|
||||||
let items: [RoomTimelineItemProtocol] = [TextRoomTimelineItem(eventID: "t1"),
|
let items: [RoomTimelineItemProtocol] = [TextRoomTimelineItem(eventID: "t1"),
|
||||||
TextRoomTimelineItem(eventID: "t2"),
|
TextRoomTimelineItem(eventID: "t2"),
|
||||||
SeparatorRoomTimelineItem(uniqueID: "v3")]
|
SeparatorRoomTimelineItem(uniqueID: .init(id: "v3"))]
|
||||||
let (viewModel, _, _, _) = readReceiptsConfiguration(with: items)
|
let (viewModel, _, _, _) = readReceiptsConfiguration(with: items)
|
||||||
|
|
||||||
// When sending a read receipt for the last item.
|
// When sending a read receipt for the last item.
|
||||||
@@ -436,14 +437,14 @@ private extension TextRoomTimelineItem {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private extension SeparatorRoomTimelineItem {
|
private extension SeparatorRoomTimelineItem {
|
||||||
init(uniqueID: String) {
|
init(uniqueID: TimelineUniqueId) {
|
||||||
self.init(id: .virtual(uniqueID: uniqueID), text: "")
|
self.init(id: .virtual(uniqueID: uniqueID), text: "")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private extension TextRoomTimelineItem {
|
private extension TextRoomTimelineItem {
|
||||||
init(eventID: String) {
|
init(eventID: String) {
|
||||||
self.init(id: .event(uniqueID: UUID().uuidString, eventOrTransactionID: .eventId(eventId: eventID)),
|
self.init(id: .event(uniqueID: .init(id: UUID().uuidString), eventOrTransactionID: .eventId(eventId: eventID)),
|
||||||
timestamp: "",
|
timestamp: "",
|
||||||
isOutgoing: false,
|
isOutgoing: false,
|
||||||
isEditable: false,
|
isEditable: false,
|
||||||
|
|||||||
+1
-1
@@ -60,7 +60,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.57
|
exactVersion: 1.0.58
|
||||||
# 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