mirror of
https://github.com/Novaloop-AG/element-x-ios.git
synced 2026-11-02 21:33:26 +00:00
Add support for sending media within threads.
This patch add the `threadRootEventID` as a parameter to media sending functions and forwards the timeline thread root between various application states to the place where its needed. The 2 missing items are Locations and Polls which currently don't have any support on the Rust side for being sent within threads. That will come in a separate PR.
This commit is contained in:
committed by
Stefan Ceriu
parent
6481093107
commit
558cdf5be3
@@ -301,8 +301,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case (_, .presentReportContent, .reportContent(let itemID, let senderID, _)):
|
||||
presentReportContent(for: itemID, from: senderID)
|
||||
|
||||
case (_, .presentMediaUploadPicker, .mediaUploadPicker(let source, _)):
|
||||
presentMediaUploadPickerWithSource(source)
|
||||
case (_, .presentMediaUploadPicker, .mediaUploadPicker(let source, let threadRootEventID, _)):
|
||||
presentMediaUploadPickerWithSource(source, threadRootEventID: threadRootEventID)
|
||||
|
||||
case (_, .presentEmojiPicker, .emojiPicker(let itemID, let selectedEmoji, _)):
|
||||
presentEmojiPicker(for: itemID, selectedEmoji: selectedEmoji)
|
||||
@@ -387,8 +387,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case (.pollsHistory, .presentPollForm(let mode), .pollsHistoryForm):
|
||||
presentPollForm(mode: mode)
|
||||
|
||||
case (_, .presentMediaUploadPreview, .mediaUploadPreview(let fileURL, _)):
|
||||
presentMediaUploadPreviewScreen(for: fileURL, animated: animated)
|
||||
case (_, .presentMediaUploadPreview, .mediaUploadPreview(let fileURL, let threadRootEventID, _)):
|
||||
presentMediaUploadPreviewScreen(for: fileURL, threadRootEventID: threadRootEventID, animated: animated)
|
||||
|
||||
case (_, .presentInviteUsersScreen, .inviteUsersScreen):
|
||||
presentInviteUsersScreen()
|
||||
@@ -441,7 +441,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case .eventFocus(let focusedEvent):
|
||||
roomScreenCoordinator?.focusOnEvent(focusedEvent)
|
||||
case .share(.mediaFile(_, let mediaFile)):
|
||||
stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: mediaFile.url), userInfo: EventUserInfo(animated: animated))
|
||||
stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: mediaFile.url, threadRootEventID: nil),
|
||||
userInfo: EventUserInfo(animated: animated))
|
||||
case .share(.text(_, let text)):
|
||||
roomScreenCoordinator?.shareText(text)
|
||||
case .none:
|
||||
@@ -477,7 +478,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
switch presentationAction {
|
||||
case .share(.mediaFile(_, let mediaFile)):
|
||||
stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: mediaFile.url), userInfo: EventUserInfo(animated: animated))
|
||||
stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: mediaFile.url, threadRootEventID: nil),
|
||||
userInfo: EventUserInfo(animated: animated))
|
||||
case .share(.text), .eventFocus:
|
||||
break // These are both handled in the coordinator's init.
|
||||
case .none:
|
||||
@@ -528,9 +530,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case .presentReportContent(let itemID, let senderID):
|
||||
stateMachine.tryEvent(.presentReportContent(itemID: itemID, senderID: senderID))
|
||||
case .presentMediaUploadPicker(let source):
|
||||
stateMachine.tryEvent(.presentMediaUploadPicker(source: source))
|
||||
stateMachine.tryEvent(.presentMediaUploadPicker(source: source, threadRootEventID: nil))
|
||||
case .presentMediaUploadPreviewScreen(let url):
|
||||
stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: url))
|
||||
stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: url, threadRootEventID: nil))
|
||||
case .presentEmojiPicker(let itemID, let selectedEmojis):
|
||||
stateMachine.tryEvent(.presentEmojiPicker(itemID: itemID, selectedEmojis: selectedEmojis))
|
||||
case .presentLocationPicker:
|
||||
@@ -605,10 +607,12 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
switch action {
|
||||
case .presentReportContent(let itemID, let senderID):
|
||||
stateMachine.tryEvent(.presentReportContent(itemID: itemID, senderID: senderID))
|
||||
case .presentMediaUploadPicker(let source):
|
||||
stateMachine.tryEvent(.presentMediaUploadPicker(source: source))
|
||||
case .presentMediaUploadPreviewScreen(let url):
|
||||
stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: url))
|
||||
case .presentMediaUploadPicker(let source, let threadRootEventID):
|
||||
stateMachine.tryEvent(.presentMediaUploadPicker(source: source,
|
||||
threadRootEventID: threadRootEventID))
|
||||
case .presentMediaUploadPreviewScreen(let url, let threadRootEventID):
|
||||
stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: url,
|
||||
threadRootEventID: threadRootEventID))
|
||||
case .presentLocationPicker:
|
||||
stateMachine.tryEvent(.presentMapNavigator(interactionMode: .picker))
|
||||
case .presentPollForm(let mode):
|
||||
@@ -867,7 +871,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
private func presentMediaUploadPickerWithSource(_ source: MediaPickerScreenSource) {
|
||||
private func presentMediaUploadPickerWithSource(_ source: MediaPickerScreenSource,
|
||||
threadRootEventID: String?) {
|
||||
let stackCoordinator = NavigationStackCoordinator()
|
||||
|
||||
let mediaPickerCoordinator = MediaPickerScreenCoordinator(userIndicatorController: userIndicatorController,
|
||||
@@ -880,7 +885,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
case .cancel:
|
||||
navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
case .selectMediaAtURL(let url):
|
||||
stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: url))
|
||||
stateMachine.tryEvent(.presentMediaUploadPreview(fileURL: url, threadRootEventID: threadRootEventID))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -893,7 +898,9 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
}
|
||||
}
|
||||
|
||||
private func presentMediaUploadPreviewScreen(for url: URL, animated: Bool) {
|
||||
private func presentMediaUploadPreviewScreen(for url: URL,
|
||||
threadRootEventID: String?,
|
||||
animated: Bool) {
|
||||
let stackCoordinator = NavigationStackCoordinator()
|
||||
|
||||
let parameters = MediaUploadPreviewScreenCoordinatorParameters(userIndicatorController: userIndicatorController,
|
||||
@@ -901,6 +908,7 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: appSettings),
|
||||
title: url.lastPathComponent,
|
||||
url: url,
|
||||
threadRootEventID: threadRootEventID,
|
||||
shouldShowCaptionWarning: appSettings.shouldShowMediaCaptionWarning)
|
||||
|
||||
let mediaUploadPreviewScreenCoordinator = MediaUploadPreviewScreenCoordinator(parameters: parameters)
|
||||
@@ -966,11 +974,13 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
switch action {
|
||||
case .selectedLocation(let geoURI, let isUserLocation):
|
||||
Task {
|
||||
#warning("Allow sending locations within threads when the SDK allows it")
|
||||
_ = await self.roomProxy.timeline.sendLocation(body: geoURI.bodyMessage,
|
||||
geoURI: geoURI,
|
||||
description: nil,
|
||||
zoomLevel: 15,
|
||||
assetType: isUserLocation ? .sender : .pin)
|
||||
assetType: isUserLocation ? .sender : .pin,
|
||||
threadRootEventID: nil)
|
||||
self.navigationStackCoordinator.setSheetCoordinator(nil)
|
||||
}
|
||||
|
||||
@@ -1028,7 +1038,8 @@ class RoomFlowCoordinator: FlowCoordinatorProtocol {
|
||||
|
||||
private func createPoll(question: String, options: [String], pollKind: Poll.Kind) {
|
||||
Task {
|
||||
let result = await roomProxy.timeline.createPoll(question: question, answers: options, pollKind: pollKind)
|
||||
#warning("Allow sending polls within threads when the SDK allows it")
|
||||
let result = await roomProxy.timeline.createPoll(question: question, answers: options, pollKind: pollKind, threadRootEventID: nil)
|
||||
|
||||
self.analytics.trackComposer(inThread: false,
|
||||
isEditing: false,
|
||||
|
||||
@@ -57,8 +57,8 @@ extension RoomFlowCoordinator {
|
||||
case roomMemberDetails(userID: String, previousState: State)
|
||||
case userProfile(userID: String, previousState: State)
|
||||
case inviteUsersScreen(previousState: State)
|
||||
case mediaUploadPicker(source: MediaPickerScreenSource, previousState: State)
|
||||
case mediaUploadPreview(fileURL: URL, previousState: State)
|
||||
case mediaUploadPicker(source: MediaPickerScreenSource, threadRootEventID: String?, previousState: State)
|
||||
case mediaUploadPreview(fileURL: URL, threadRootEventID: String?, previousState: State)
|
||||
case emojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set<String>, previousState: State)
|
||||
case mapNavigator(previousState: State)
|
||||
case messageForwarding(forwardingItem: MessageForwardingItem, previousState: State)
|
||||
@@ -122,10 +122,10 @@ extension RoomFlowCoordinator {
|
||||
case presentInviteUsersScreen
|
||||
case dismissInviteUsersScreen
|
||||
|
||||
case presentMediaUploadPicker(source: MediaPickerScreenSource)
|
||||
case presentMediaUploadPicker(source: MediaPickerScreenSource, threadRootEventID: String?)
|
||||
case dismissMediaUploadPicker
|
||||
|
||||
case presentMediaUploadPreview(fileURL: URL)
|
||||
case presentMediaUploadPreview(fileURL: URL, threadRootEventID: String?)
|
||||
case dismissMediaUploadPreview
|
||||
|
||||
case presentEmojiPicker(itemID: TimelineItemIdentifier, selectedEmojis: Set<String>)
|
||||
@@ -184,11 +184,11 @@ extension RoomFlowCoordinator {
|
||||
case (.room, .presentReportContent(let itemID, let senderID)):
|
||||
return .reportContent(itemID: itemID, senderID: senderID, previousState: fromState)
|
||||
|
||||
case (.room, .presentMediaUploadPicker(let source)):
|
||||
return .mediaUploadPicker(source: source, previousState: fromState)
|
||||
case (.room, .presentMediaUploadPicker(let source, let threadRootEventID)):
|
||||
return .mediaUploadPicker(source: source, threadRootEventID: threadRootEventID, previousState: fromState)
|
||||
|
||||
case (.room, .presentMediaUploadPreview(let fileURL)):
|
||||
return .mediaUploadPreview(fileURL: fileURL, previousState: fromState)
|
||||
case (.room, .presentMediaUploadPreview(let fileURL, let threadRootEventID)):
|
||||
return .mediaUploadPreview(fileURL: fileURL, threadRootEventID: threadRootEventID, previousState: fromState)
|
||||
|
||||
case (.room, .presentEmojiPicker(let itemID, let selectedEmoji)):
|
||||
return .emojiPicker(itemID: itemID, selectedEmojis: selectedEmoji, previousState: fromState)
|
||||
@@ -221,11 +221,11 @@ extension RoomFlowCoordinator {
|
||||
case (.thread, .presentReportContent(let itemID, let senderID)):
|
||||
return .reportContent(itemID: itemID, senderID: senderID, previousState: fromState)
|
||||
|
||||
case (.thread, .presentMediaUploadPicker(let source)):
|
||||
return .mediaUploadPicker(source: source, previousState: fromState)
|
||||
case (.thread, .presentMediaUploadPicker(let source, let threadRootEventID)):
|
||||
return .mediaUploadPicker(source: source, threadRootEventID: threadRootEventID, previousState: fromState)
|
||||
|
||||
case (.thread, .presentMediaUploadPreview(let fileURL)):
|
||||
return .mediaUploadPreview(fileURL: fileURL, previousState: fromState)
|
||||
case (.thread, .presentMediaUploadPreview(let fileURL, let threadRootEventID)):
|
||||
return .mediaUploadPreview(fileURL: fileURL, threadRootEventID: threadRootEventID, previousState: fromState)
|
||||
|
||||
case (.thread, .presentEmojiPicker(let itemID, let selectedEmoji)):
|
||||
return .emojiPicker(itemID: itemID, selectedEmojis: selectedEmoji, previousState: fromState)
|
||||
@@ -244,7 +244,7 @@ extension RoomFlowCoordinator {
|
||||
|
||||
// Room + Thread
|
||||
|
||||
case (.mediaUploadPicker(_, let previousState), .dismissMediaUploadPicker):
|
||||
case (.mediaUploadPicker(_, _, let previousState), .dismissMediaUploadPicker):
|
||||
return previousState
|
||||
|
||||
case (.emojiPicker(_, _, let previouState), .dismissEmojiPicker):
|
||||
@@ -343,7 +343,7 @@ extension RoomFlowCoordinator {
|
||||
case (.knockRequestsList(let previousState), .dismissKnockRequestsListScreen):
|
||||
return previousState
|
||||
|
||||
case (.mediaUploadPreview(_, let previousState), .dismissMediaUploadPreview):
|
||||
case (.mediaUploadPreview(_, _, let previousState), .dismissMediaUploadPreview):
|
||||
return previousState
|
||||
|
||||
case (.notificationSettings, .presentGlobalNotificationSettingsScreen):
|
||||
@@ -361,8 +361,8 @@ extension RoomFlowCoordinator {
|
||||
case (.pollsHistoryForm, .dismissPollForm):
|
||||
return .pollsHistory
|
||||
|
||||
case (.mediaUploadPicker(_, let previousMediaUploadPickerState), .presentMediaUploadPreview(let fileURL)):
|
||||
return .mediaUploadPreview(fileURL: fileURL, previousState: previousMediaUploadPickerState)
|
||||
case (.mediaUploadPicker(_, _, let previousMediaUploadPickerState), .presentMediaUploadPreview(let fileURL, let threadRootEventID)):
|
||||
return .mediaUploadPreview(fileURL: fileURL, threadRootEventID: threadRootEventID, previousState: previousMediaUploadPickerState)
|
||||
|
||||
case (_, .presentInviteUsersScreen):
|
||||
return .inviteUsersScreen(previousState: fromState)
|
||||
|
||||
@@ -16153,15 +16153,15 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
//MARK: - sendAudio
|
||||
|
||||
var sendAudioUrlAudioInfoCaptionRequestHandleUnderlyingCallsCount = 0
|
||||
var sendAudioUrlAudioInfoCaptionRequestHandleCallsCount: Int {
|
||||
var sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount = 0
|
||||
var sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return sendAudioUrlAudioInfoCaptionRequestHandleUnderlyingCallsCount
|
||||
return sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = sendAudioUrlAudioInfoCaptionRequestHandleUnderlyingCallsCount
|
||||
returnValue = sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16169,27 +16169,27 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
sendAudioUrlAudioInfoCaptionRequestHandleUnderlyingCallsCount = newValue
|
||||
sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
sendAudioUrlAudioInfoCaptionRequestHandleUnderlyingCallsCount = newValue
|
||||
sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var sendAudioUrlAudioInfoCaptionRequestHandleCalled: Bool {
|
||||
return sendAudioUrlAudioInfoCaptionRequestHandleCallsCount > 0
|
||||
var sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleCalled: Bool {
|
||||
return sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleCallsCount > 0
|
||||
}
|
||||
|
||||
var sendAudioUrlAudioInfoCaptionRequestHandleUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||
var sendAudioUrlAudioInfoCaptionRequestHandleReturnValue: Result<Void, TimelineProxyError>! {
|
||||
var sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||
var sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleReturnValue: Result<Void, TimelineProxyError>! {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return sendAudioUrlAudioInfoCaptionRequestHandleUnderlyingReturnValue
|
||||
return sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue
|
||||
} else {
|
||||
var returnValue: Result<Void, TimelineProxyError>? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = sendAudioUrlAudioInfoCaptionRequestHandleUnderlyingReturnValue
|
||||
returnValue = sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16197,35 +16197,35 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
sendAudioUrlAudioInfoCaptionRequestHandleUnderlyingReturnValue = newValue
|
||||
sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
sendAudioUrlAudioInfoCaptionRequestHandleUnderlyingReturnValue = newValue
|
||||
sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var sendAudioUrlAudioInfoCaptionRequestHandleClosure: ((URL, AudioInfo, String?, @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>)?
|
||||
var sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleClosure: ((URL, AudioInfo, String?, String?, @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>)?
|
||||
|
||||
func sendAudio(url: URL, audioInfo: AudioInfo, caption: String?, requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
sendAudioUrlAudioInfoCaptionRequestHandleCallsCount += 1
|
||||
if let sendAudioUrlAudioInfoCaptionRequestHandleClosure = sendAudioUrlAudioInfoCaptionRequestHandleClosure {
|
||||
return await sendAudioUrlAudioInfoCaptionRequestHandleClosure(url, audioInfo, caption, requestHandle)
|
||||
func sendAudio(url: URL, audioInfo: AudioInfo, caption: String?, threadRootEventID: String?, requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleCallsCount += 1
|
||||
if let sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleClosure = sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleClosure {
|
||||
return await sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleClosure(url, audioInfo, caption, threadRootEventID, requestHandle)
|
||||
} else {
|
||||
return sendAudioUrlAudioInfoCaptionRequestHandleReturnValue
|
||||
return sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleReturnValue
|
||||
}
|
||||
}
|
||||
//MARK: - sendFile
|
||||
|
||||
var sendFileUrlFileInfoCaptionRequestHandleUnderlyingCallsCount = 0
|
||||
var sendFileUrlFileInfoCaptionRequestHandleCallsCount: Int {
|
||||
var sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount = 0
|
||||
var sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return sendFileUrlFileInfoCaptionRequestHandleUnderlyingCallsCount
|
||||
return sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = sendFileUrlFileInfoCaptionRequestHandleUnderlyingCallsCount
|
||||
returnValue = sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16233,27 +16233,27 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
sendFileUrlFileInfoCaptionRequestHandleUnderlyingCallsCount = newValue
|
||||
sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
sendFileUrlFileInfoCaptionRequestHandleUnderlyingCallsCount = newValue
|
||||
sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var sendFileUrlFileInfoCaptionRequestHandleCalled: Bool {
|
||||
return sendFileUrlFileInfoCaptionRequestHandleCallsCount > 0
|
||||
var sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleCalled: Bool {
|
||||
return sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleCallsCount > 0
|
||||
}
|
||||
|
||||
var sendFileUrlFileInfoCaptionRequestHandleUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||
var sendFileUrlFileInfoCaptionRequestHandleReturnValue: Result<Void, TimelineProxyError>! {
|
||||
var sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||
var sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleReturnValue: Result<Void, TimelineProxyError>! {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return sendFileUrlFileInfoCaptionRequestHandleUnderlyingReturnValue
|
||||
return sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue
|
||||
} else {
|
||||
var returnValue: Result<Void, TimelineProxyError>? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = sendFileUrlFileInfoCaptionRequestHandleUnderlyingReturnValue
|
||||
returnValue = sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16261,35 +16261,35 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
sendFileUrlFileInfoCaptionRequestHandleUnderlyingReturnValue = newValue
|
||||
sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
sendFileUrlFileInfoCaptionRequestHandleUnderlyingReturnValue = newValue
|
||||
sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var sendFileUrlFileInfoCaptionRequestHandleClosure: ((URL, FileInfo, String?, @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>)?
|
||||
var sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleClosure: ((URL, FileInfo, String?, String?, @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>)?
|
||||
|
||||
func sendFile(url: URL, fileInfo: FileInfo, caption: String?, requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
sendFileUrlFileInfoCaptionRequestHandleCallsCount += 1
|
||||
if let sendFileUrlFileInfoCaptionRequestHandleClosure = sendFileUrlFileInfoCaptionRequestHandleClosure {
|
||||
return await sendFileUrlFileInfoCaptionRequestHandleClosure(url, fileInfo, caption, requestHandle)
|
||||
func sendFile(url: URL, fileInfo: FileInfo, caption: String?, threadRootEventID: String?, requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleCallsCount += 1
|
||||
if let sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleClosure = sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleClosure {
|
||||
return await sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleClosure(url, fileInfo, caption, threadRootEventID, requestHandle)
|
||||
} else {
|
||||
return sendFileUrlFileInfoCaptionRequestHandleReturnValue
|
||||
return sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleReturnValue
|
||||
}
|
||||
}
|
||||
//MARK: - sendImage
|
||||
|
||||
var sendImageUrlThumbnailURLImageInfoCaptionRequestHandleUnderlyingCallsCount = 0
|
||||
var sendImageUrlThumbnailURLImageInfoCaptionRequestHandleCallsCount: Int {
|
||||
var sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount = 0
|
||||
var sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return sendImageUrlThumbnailURLImageInfoCaptionRequestHandleUnderlyingCallsCount
|
||||
return sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = sendImageUrlThumbnailURLImageInfoCaptionRequestHandleUnderlyingCallsCount
|
||||
returnValue = sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16297,27 +16297,27 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
sendImageUrlThumbnailURLImageInfoCaptionRequestHandleUnderlyingCallsCount = newValue
|
||||
sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
sendImageUrlThumbnailURLImageInfoCaptionRequestHandleUnderlyingCallsCount = newValue
|
||||
sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var sendImageUrlThumbnailURLImageInfoCaptionRequestHandleCalled: Bool {
|
||||
return sendImageUrlThumbnailURLImageInfoCaptionRequestHandleCallsCount > 0
|
||||
var sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleCalled: Bool {
|
||||
return sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleCallsCount > 0
|
||||
}
|
||||
|
||||
var sendImageUrlThumbnailURLImageInfoCaptionRequestHandleUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||
var sendImageUrlThumbnailURLImageInfoCaptionRequestHandleReturnValue: Result<Void, TimelineProxyError>! {
|
||||
var sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||
var sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleReturnValue: Result<Void, TimelineProxyError>! {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return sendImageUrlThumbnailURLImageInfoCaptionRequestHandleUnderlyingReturnValue
|
||||
return sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue
|
||||
} else {
|
||||
var returnValue: Result<Void, TimelineProxyError>? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = sendImageUrlThumbnailURLImageInfoCaptionRequestHandleUnderlyingReturnValue
|
||||
returnValue = sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16325,35 +16325,35 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
sendImageUrlThumbnailURLImageInfoCaptionRequestHandleUnderlyingReturnValue = newValue
|
||||
sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
sendImageUrlThumbnailURLImageInfoCaptionRequestHandleUnderlyingReturnValue = newValue
|
||||
sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var sendImageUrlThumbnailURLImageInfoCaptionRequestHandleClosure: ((URL, URL, ImageInfo, String?, @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>)?
|
||||
var sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleClosure: ((URL, URL, ImageInfo, String?, String?, @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>)?
|
||||
|
||||
func sendImage(url: URL, thumbnailURL: URL, imageInfo: ImageInfo, caption: String?, requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
sendImageUrlThumbnailURLImageInfoCaptionRequestHandleCallsCount += 1
|
||||
if let sendImageUrlThumbnailURLImageInfoCaptionRequestHandleClosure = sendImageUrlThumbnailURLImageInfoCaptionRequestHandleClosure {
|
||||
return await sendImageUrlThumbnailURLImageInfoCaptionRequestHandleClosure(url, thumbnailURL, imageInfo, caption, requestHandle)
|
||||
func sendImage(url: URL, thumbnailURL: URL, imageInfo: ImageInfo, caption: String?, threadRootEventID: String?, requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleCallsCount += 1
|
||||
if let sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleClosure = sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleClosure {
|
||||
return await sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleClosure(url, thumbnailURL, imageInfo, caption, threadRootEventID, requestHandle)
|
||||
} else {
|
||||
return sendImageUrlThumbnailURLImageInfoCaptionRequestHandleReturnValue
|
||||
return sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleReturnValue
|
||||
}
|
||||
}
|
||||
//MARK: - sendLocation
|
||||
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeUnderlyingCallsCount = 0
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeCallsCount: Int {
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDUnderlyingCallsCount = 0
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeUnderlyingCallsCount
|
||||
return sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeUnderlyingCallsCount
|
||||
returnValue = sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16361,29 +16361,29 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeUnderlyingCallsCount = newValue
|
||||
sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeUnderlyingCallsCount = newValue
|
||||
sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeCalled: Bool {
|
||||
return sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeCallsCount > 0
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDCalled: Bool {
|
||||
return sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDCallsCount > 0
|
||||
}
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeReceivedArguments: (body: String, geoURI: GeoURI, description: String?, zoomLevel: UInt8?, assetType: AssetType?)?
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeReceivedInvocations: [(body: String, geoURI: GeoURI, description: String?, zoomLevel: UInt8?, assetType: AssetType?)] = []
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDReceivedArguments: (body: String, geoURI: GeoURI, description: String?, zoomLevel: UInt8?, assetType: AssetType?, threadRootEventID: String?)?
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDReceivedInvocations: [(body: String, geoURI: GeoURI, description: String?, zoomLevel: UInt8?, assetType: AssetType?, threadRootEventID: String?)] = []
|
||||
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeReturnValue: Result<Void, TimelineProxyError>! {
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDReturnValue: Result<Void, TimelineProxyError>! {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeUnderlyingReturnValue
|
||||
return sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDUnderlyingReturnValue
|
||||
} else {
|
||||
var returnValue: Result<Void, TimelineProxyError>? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeUnderlyingReturnValue
|
||||
returnValue = sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDUnderlyingReturnValue
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16391,39 +16391,39 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeUnderlyingReturnValue = newValue
|
||||
sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDUnderlyingReturnValue = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeUnderlyingReturnValue = newValue
|
||||
sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDUnderlyingReturnValue = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeClosure: ((String, GeoURI, String?, UInt8?, AssetType?) async -> Result<Void, TimelineProxyError>)?
|
||||
var sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDClosure: ((String, GeoURI, String?, UInt8?, AssetType?, String?) async -> Result<Void, TimelineProxyError>)?
|
||||
|
||||
func sendLocation(body: String, geoURI: GeoURI, description: String?, zoomLevel: UInt8?, assetType: AssetType?) async -> Result<Void, TimelineProxyError> {
|
||||
sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeCallsCount += 1
|
||||
sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeReceivedArguments = (body: body, geoURI: geoURI, description: description, zoomLevel: zoomLevel, assetType: assetType)
|
||||
func sendLocation(body: String, geoURI: GeoURI, description: String?, zoomLevel: UInt8?, assetType: AssetType?, threadRootEventID: String?) async -> Result<Void, TimelineProxyError> {
|
||||
sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDCallsCount += 1
|
||||
sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDReceivedArguments = (body: body, geoURI: geoURI, description: description, zoomLevel: zoomLevel, assetType: assetType, threadRootEventID: threadRootEventID)
|
||||
DispatchQueue.main.async {
|
||||
self.sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeReceivedInvocations.append((body: body, geoURI: geoURI, description: description, zoomLevel: zoomLevel, assetType: assetType))
|
||||
self.sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDReceivedInvocations.append((body: body, geoURI: geoURI, description: description, zoomLevel: zoomLevel, assetType: assetType, threadRootEventID: threadRootEventID))
|
||||
}
|
||||
if let sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeClosure = sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeClosure {
|
||||
return await sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeClosure(body, geoURI, description, zoomLevel, assetType)
|
||||
if let sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDClosure = sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDClosure {
|
||||
return await sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDClosure(body, geoURI, description, zoomLevel, assetType, threadRootEventID)
|
||||
} else {
|
||||
return sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeReturnValue
|
||||
return sendLocationBodyGeoURIDescriptionZoomLevelAssetTypeThreadRootEventIDReturnValue
|
||||
}
|
||||
}
|
||||
//MARK: - sendVideo
|
||||
|
||||
var sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleUnderlyingCallsCount = 0
|
||||
var sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleCallsCount: Int {
|
||||
var sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount = 0
|
||||
var sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleUnderlyingCallsCount
|
||||
return sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleUnderlyingCallsCount
|
||||
returnValue = sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16431,27 +16431,27 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleUnderlyingCallsCount = newValue
|
||||
sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleUnderlyingCallsCount = newValue
|
||||
sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleCalled: Bool {
|
||||
return sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleCallsCount > 0
|
||||
var sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleCalled: Bool {
|
||||
return sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleCallsCount > 0
|
||||
}
|
||||
|
||||
var sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||
var sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleReturnValue: Result<Void, TimelineProxyError>! {
|
||||
var sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||
var sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleReturnValue: Result<Void, TimelineProxyError>! {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleUnderlyingReturnValue
|
||||
return sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue
|
||||
} else {
|
||||
var returnValue: Result<Void, TimelineProxyError>? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleUnderlyingReturnValue
|
||||
returnValue = sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16459,35 +16459,35 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleUnderlyingReturnValue = newValue
|
||||
sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleUnderlyingReturnValue = newValue
|
||||
sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleUnderlyingReturnValue = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleClosure: ((URL, URL, VideoInfo, String?, @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>)?
|
||||
var sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleClosure: ((URL, URL, VideoInfo, String?, String?, @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>)?
|
||||
|
||||
func sendVideo(url: URL, thumbnailURL: URL, videoInfo: VideoInfo, caption: String?, requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleCallsCount += 1
|
||||
if let sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleClosure = sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleClosure {
|
||||
return await sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleClosure(url, thumbnailURL, videoInfo, caption, requestHandle)
|
||||
func sendVideo(url: URL, thumbnailURL: URL, videoInfo: VideoInfo, caption: String?, threadRootEventID: String?, requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleCallsCount += 1
|
||||
if let sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleClosure = sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleClosure {
|
||||
return await sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleClosure(url, thumbnailURL, videoInfo, caption, threadRootEventID, requestHandle)
|
||||
} else {
|
||||
return sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleReturnValue
|
||||
return sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleReturnValue
|
||||
}
|
||||
}
|
||||
//MARK: - sendVoiceMessage
|
||||
|
||||
var sendVoiceMessageUrlAudioInfoWaveformRequestHandleUnderlyingCallsCount = 0
|
||||
var sendVoiceMessageUrlAudioInfoWaveformRequestHandleCallsCount: Int {
|
||||
var sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleUnderlyingCallsCount = 0
|
||||
var sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return sendVoiceMessageUrlAudioInfoWaveformRequestHandleUnderlyingCallsCount
|
||||
return sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = sendVoiceMessageUrlAudioInfoWaveformRequestHandleUnderlyingCallsCount
|
||||
returnValue = sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16495,27 +16495,27 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
sendVoiceMessageUrlAudioInfoWaveformRequestHandleUnderlyingCallsCount = newValue
|
||||
sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
sendVoiceMessageUrlAudioInfoWaveformRequestHandleUnderlyingCallsCount = newValue
|
||||
sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var sendVoiceMessageUrlAudioInfoWaveformRequestHandleCalled: Bool {
|
||||
return sendVoiceMessageUrlAudioInfoWaveformRequestHandleCallsCount > 0
|
||||
var sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleCalled: Bool {
|
||||
return sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleCallsCount > 0
|
||||
}
|
||||
|
||||
var sendVoiceMessageUrlAudioInfoWaveformRequestHandleUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||
var sendVoiceMessageUrlAudioInfoWaveformRequestHandleReturnValue: Result<Void, TimelineProxyError>! {
|
||||
var sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||
var sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleReturnValue: Result<Void, TimelineProxyError>! {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return sendVoiceMessageUrlAudioInfoWaveformRequestHandleUnderlyingReturnValue
|
||||
return sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleUnderlyingReturnValue
|
||||
} else {
|
||||
var returnValue: Result<Void, TimelineProxyError>? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = sendVoiceMessageUrlAudioInfoWaveformRequestHandleUnderlyingReturnValue
|
||||
returnValue = sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleUnderlyingReturnValue
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16523,22 +16523,22 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
sendVoiceMessageUrlAudioInfoWaveformRequestHandleUnderlyingReturnValue = newValue
|
||||
sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleUnderlyingReturnValue = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
sendVoiceMessageUrlAudioInfoWaveformRequestHandleUnderlyingReturnValue = newValue
|
||||
sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleUnderlyingReturnValue = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var sendVoiceMessageUrlAudioInfoWaveformRequestHandleClosure: ((URL, AudioInfo, [UInt16], @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>)?
|
||||
var sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleClosure: ((URL, AudioInfo, [UInt16], String?, @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>)?
|
||||
|
||||
func sendVoiceMessage(url: URL, audioInfo: AudioInfo, waveform: [UInt16], requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
sendVoiceMessageUrlAudioInfoWaveformRequestHandleCallsCount += 1
|
||||
if let sendVoiceMessageUrlAudioInfoWaveformRequestHandleClosure = sendVoiceMessageUrlAudioInfoWaveformRequestHandleClosure {
|
||||
return await sendVoiceMessageUrlAudioInfoWaveformRequestHandleClosure(url, audioInfo, waveform, requestHandle)
|
||||
func sendVoiceMessage(url: URL, audioInfo: AudioInfo, waveform: [UInt16], threadRootEventID: String?, requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleCallsCount += 1
|
||||
if let sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleClosure = sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleClosure {
|
||||
return await sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleClosure(url, audioInfo, waveform, threadRootEventID, requestHandle)
|
||||
} else {
|
||||
return sendVoiceMessageUrlAudioInfoWaveformRequestHandleReturnValue
|
||||
return sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleReturnValue
|
||||
}
|
||||
}
|
||||
//MARK: - sendReadReceipt
|
||||
@@ -16823,15 +16823,15 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
//MARK: - createPoll
|
||||
|
||||
var createPollQuestionAnswersPollKindUnderlyingCallsCount = 0
|
||||
var createPollQuestionAnswersPollKindCallsCount: Int {
|
||||
var createPollQuestionAnswersPollKindThreadRootEventIDUnderlyingCallsCount = 0
|
||||
var createPollQuestionAnswersPollKindThreadRootEventIDCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return createPollQuestionAnswersPollKindUnderlyingCallsCount
|
||||
return createPollQuestionAnswersPollKindThreadRootEventIDUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = createPollQuestionAnswersPollKindUnderlyingCallsCount
|
||||
returnValue = createPollQuestionAnswersPollKindThreadRootEventIDUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16839,29 +16839,29 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
createPollQuestionAnswersPollKindUnderlyingCallsCount = newValue
|
||||
createPollQuestionAnswersPollKindThreadRootEventIDUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
createPollQuestionAnswersPollKindUnderlyingCallsCount = newValue
|
||||
createPollQuestionAnswersPollKindThreadRootEventIDUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var createPollQuestionAnswersPollKindCalled: Bool {
|
||||
return createPollQuestionAnswersPollKindCallsCount > 0
|
||||
var createPollQuestionAnswersPollKindThreadRootEventIDCalled: Bool {
|
||||
return createPollQuestionAnswersPollKindThreadRootEventIDCallsCount > 0
|
||||
}
|
||||
var createPollQuestionAnswersPollKindReceivedArguments: (question: String, answers: [String], pollKind: Poll.Kind)?
|
||||
var createPollQuestionAnswersPollKindReceivedInvocations: [(question: String, answers: [String], pollKind: Poll.Kind)] = []
|
||||
var createPollQuestionAnswersPollKindThreadRootEventIDReceivedArguments: (question: String, answers: [String], pollKind: Poll.Kind, threadRootEventID: String?)?
|
||||
var createPollQuestionAnswersPollKindThreadRootEventIDReceivedInvocations: [(question: String, answers: [String], pollKind: Poll.Kind, threadRootEventID: String?)] = []
|
||||
|
||||
var createPollQuestionAnswersPollKindUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||
var createPollQuestionAnswersPollKindReturnValue: Result<Void, TimelineProxyError>! {
|
||||
var createPollQuestionAnswersPollKindThreadRootEventIDUnderlyingReturnValue: Result<Void, TimelineProxyError>!
|
||||
var createPollQuestionAnswersPollKindThreadRootEventIDReturnValue: Result<Void, TimelineProxyError>! {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return createPollQuestionAnswersPollKindUnderlyingReturnValue
|
||||
return createPollQuestionAnswersPollKindThreadRootEventIDUnderlyingReturnValue
|
||||
} else {
|
||||
var returnValue: Result<Void, TimelineProxyError>? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = createPollQuestionAnswersPollKindUnderlyingReturnValue
|
||||
returnValue = createPollQuestionAnswersPollKindThreadRootEventIDUnderlyingReturnValue
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -16869,26 +16869,26 @@ class TimelineProxyMock: TimelineProxyProtocol, @unchecked Sendable {
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
createPollQuestionAnswersPollKindUnderlyingReturnValue = newValue
|
||||
createPollQuestionAnswersPollKindThreadRootEventIDUnderlyingReturnValue = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
createPollQuestionAnswersPollKindUnderlyingReturnValue = newValue
|
||||
createPollQuestionAnswersPollKindThreadRootEventIDUnderlyingReturnValue = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var createPollQuestionAnswersPollKindClosure: ((String, [String], Poll.Kind) async -> Result<Void, TimelineProxyError>)?
|
||||
var createPollQuestionAnswersPollKindThreadRootEventIDClosure: ((String, [String], Poll.Kind, String?) async -> Result<Void, TimelineProxyError>)?
|
||||
|
||||
func createPoll(question: String, answers: [String], pollKind: Poll.Kind) async -> Result<Void, TimelineProxyError> {
|
||||
createPollQuestionAnswersPollKindCallsCount += 1
|
||||
createPollQuestionAnswersPollKindReceivedArguments = (question: question, answers: answers, pollKind: pollKind)
|
||||
func createPoll(question: String, answers: [String], pollKind: Poll.Kind, threadRootEventID: String?) async -> Result<Void, TimelineProxyError> {
|
||||
createPollQuestionAnswersPollKindThreadRootEventIDCallsCount += 1
|
||||
createPollQuestionAnswersPollKindThreadRootEventIDReceivedArguments = (question: question, answers: answers, pollKind: pollKind, threadRootEventID: threadRootEventID)
|
||||
DispatchQueue.main.async {
|
||||
self.createPollQuestionAnswersPollKindReceivedInvocations.append((question: question, answers: answers, pollKind: pollKind))
|
||||
self.createPollQuestionAnswersPollKindThreadRootEventIDReceivedInvocations.append((question: question, answers: answers, pollKind: pollKind, threadRootEventID: threadRootEventID))
|
||||
}
|
||||
if let createPollQuestionAnswersPollKindClosure = createPollQuestionAnswersPollKindClosure {
|
||||
return await createPollQuestionAnswersPollKindClosure(question, answers, pollKind)
|
||||
if let createPollQuestionAnswersPollKindThreadRootEventIDClosure = createPollQuestionAnswersPollKindThreadRootEventIDClosure {
|
||||
return await createPollQuestionAnswersPollKindThreadRootEventIDClosure(question, answers, pollKind, threadRootEventID)
|
||||
} else {
|
||||
return createPollQuestionAnswersPollKindReturnValue
|
||||
return createPollQuestionAnswersPollKindThreadRootEventIDReturnValue
|
||||
}
|
||||
}
|
||||
//MARK: - editPoll
|
||||
@@ -18819,15 +18819,15 @@ class VoiceMessageRecorderMock: VoiceMessageRecorderProtocol, @unchecked Sendabl
|
||||
}
|
||||
//MARK: - sendVoiceMessage
|
||||
|
||||
var sendVoiceMessageInRoomAudioConverterUnderlyingCallsCount = 0
|
||||
var sendVoiceMessageInRoomAudioConverterCallsCount: Int {
|
||||
var sendVoiceMessageInRoomAudioConverterThreadRootEventIDUnderlyingCallsCount = 0
|
||||
var sendVoiceMessageInRoomAudioConverterThreadRootEventIDCallsCount: Int {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return sendVoiceMessageInRoomAudioConverterUnderlyingCallsCount
|
||||
return sendVoiceMessageInRoomAudioConverterThreadRootEventIDUnderlyingCallsCount
|
||||
} else {
|
||||
var returnValue: Int? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = sendVoiceMessageInRoomAudioConverterUnderlyingCallsCount
|
||||
returnValue = sendVoiceMessageInRoomAudioConverterThreadRootEventIDUnderlyingCallsCount
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -18835,29 +18835,29 @@ class VoiceMessageRecorderMock: VoiceMessageRecorderProtocol, @unchecked Sendabl
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
sendVoiceMessageInRoomAudioConverterUnderlyingCallsCount = newValue
|
||||
sendVoiceMessageInRoomAudioConverterThreadRootEventIDUnderlyingCallsCount = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
sendVoiceMessageInRoomAudioConverterUnderlyingCallsCount = newValue
|
||||
sendVoiceMessageInRoomAudioConverterThreadRootEventIDUnderlyingCallsCount = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var sendVoiceMessageInRoomAudioConverterCalled: Bool {
|
||||
return sendVoiceMessageInRoomAudioConverterCallsCount > 0
|
||||
var sendVoiceMessageInRoomAudioConverterThreadRootEventIDCalled: Bool {
|
||||
return sendVoiceMessageInRoomAudioConverterThreadRootEventIDCallsCount > 0
|
||||
}
|
||||
var sendVoiceMessageInRoomAudioConverterReceivedArguments: (roomProxy: JoinedRoomProxyProtocol, audioConverter: AudioConverterProtocol)?
|
||||
var sendVoiceMessageInRoomAudioConverterReceivedInvocations: [(roomProxy: JoinedRoomProxyProtocol, audioConverter: AudioConverterProtocol)] = []
|
||||
var sendVoiceMessageInRoomAudioConverterThreadRootEventIDReceivedArguments: (roomProxy: JoinedRoomProxyProtocol, audioConverter: AudioConverterProtocol, threadRootEventID: String?)?
|
||||
var sendVoiceMessageInRoomAudioConverterThreadRootEventIDReceivedInvocations: [(roomProxy: JoinedRoomProxyProtocol, audioConverter: AudioConverterProtocol, threadRootEventID: String?)] = []
|
||||
|
||||
var sendVoiceMessageInRoomAudioConverterUnderlyingReturnValue: Result<Void, VoiceMessageRecorderError>!
|
||||
var sendVoiceMessageInRoomAudioConverterReturnValue: Result<Void, VoiceMessageRecorderError>! {
|
||||
var sendVoiceMessageInRoomAudioConverterThreadRootEventIDUnderlyingReturnValue: Result<Void, VoiceMessageRecorderError>!
|
||||
var sendVoiceMessageInRoomAudioConverterThreadRootEventIDReturnValue: Result<Void, VoiceMessageRecorderError>! {
|
||||
get {
|
||||
if Thread.isMainThread {
|
||||
return sendVoiceMessageInRoomAudioConverterUnderlyingReturnValue
|
||||
return sendVoiceMessageInRoomAudioConverterThreadRootEventIDUnderlyingReturnValue
|
||||
} else {
|
||||
var returnValue: Result<Void, VoiceMessageRecorderError>? = nil
|
||||
DispatchQueue.main.sync {
|
||||
returnValue = sendVoiceMessageInRoomAudioConverterUnderlyingReturnValue
|
||||
returnValue = sendVoiceMessageInRoomAudioConverterThreadRootEventIDUnderlyingReturnValue
|
||||
}
|
||||
|
||||
return returnValue!
|
||||
@@ -18865,26 +18865,26 @@ class VoiceMessageRecorderMock: VoiceMessageRecorderProtocol, @unchecked Sendabl
|
||||
}
|
||||
set {
|
||||
if Thread.isMainThread {
|
||||
sendVoiceMessageInRoomAudioConverterUnderlyingReturnValue = newValue
|
||||
sendVoiceMessageInRoomAudioConverterThreadRootEventIDUnderlyingReturnValue = newValue
|
||||
} else {
|
||||
DispatchQueue.main.sync {
|
||||
sendVoiceMessageInRoomAudioConverterUnderlyingReturnValue = newValue
|
||||
sendVoiceMessageInRoomAudioConverterThreadRootEventIDUnderlyingReturnValue = newValue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
var sendVoiceMessageInRoomAudioConverterClosure: ((JoinedRoomProxyProtocol, AudioConverterProtocol) async -> Result<Void, VoiceMessageRecorderError>)?
|
||||
var sendVoiceMessageInRoomAudioConverterThreadRootEventIDClosure: ((JoinedRoomProxyProtocol, AudioConverterProtocol, String?) async -> Result<Void, VoiceMessageRecorderError>)?
|
||||
|
||||
func sendVoiceMessage(inRoom roomProxy: JoinedRoomProxyProtocol, audioConverter: AudioConverterProtocol) async -> Result<Void, VoiceMessageRecorderError> {
|
||||
sendVoiceMessageInRoomAudioConverterCallsCount += 1
|
||||
sendVoiceMessageInRoomAudioConverterReceivedArguments = (roomProxy: roomProxy, audioConverter: audioConverter)
|
||||
func sendVoiceMessage(inRoom roomProxy: JoinedRoomProxyProtocol, audioConverter: AudioConverterProtocol, threadRootEventID: String?) async -> Result<Void, VoiceMessageRecorderError> {
|
||||
sendVoiceMessageInRoomAudioConverterThreadRootEventIDCallsCount += 1
|
||||
sendVoiceMessageInRoomAudioConverterThreadRootEventIDReceivedArguments = (roomProxy: roomProxy, audioConverter: audioConverter, threadRootEventID: threadRootEventID)
|
||||
DispatchQueue.main.async {
|
||||
self.sendVoiceMessageInRoomAudioConverterReceivedInvocations.append((roomProxy: roomProxy, audioConverter: audioConverter))
|
||||
self.sendVoiceMessageInRoomAudioConverterThreadRootEventIDReceivedInvocations.append((roomProxy: roomProxy, audioConverter: audioConverter, threadRootEventID: threadRootEventID))
|
||||
}
|
||||
if let sendVoiceMessageInRoomAudioConverterClosure = sendVoiceMessageInRoomAudioConverterClosure {
|
||||
return await sendVoiceMessageInRoomAudioConverterClosure(roomProxy, audioConverter)
|
||||
if let sendVoiceMessageInRoomAudioConverterThreadRootEventIDClosure = sendVoiceMessageInRoomAudioConverterThreadRootEventIDClosure {
|
||||
return await sendVoiceMessageInRoomAudioConverterThreadRootEventIDClosure(roomProxy, audioConverter, threadRootEventID)
|
||||
} else {
|
||||
return sendVoiceMessageInRoomAudioConverterReturnValue
|
||||
return sendVoiceMessageInRoomAudioConverterThreadRootEventIDReturnValue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+2
@@ -14,6 +14,7 @@ struct MediaUploadPreviewScreenCoordinatorParameters {
|
||||
let mediaUploadingPreprocessor: MediaUploadingPreprocessor
|
||||
let title: String?
|
||||
let url: URL
|
||||
let threadRootEventID: String?
|
||||
let shouldShowCaptionWarning: Bool
|
||||
}
|
||||
|
||||
@@ -36,6 +37,7 @@ final class MediaUploadPreviewScreenCoordinator: CoordinatorProtocol {
|
||||
mediaUploadingPreprocessor: parameters.mediaUploadingPreprocessor,
|
||||
title: parameters.title,
|
||||
url: parameters.url,
|
||||
threadRootEventID: parameters.threadRootEventID,
|
||||
shouldShowCaptionWarning: parameters.shouldShowCaptionWarning)
|
||||
}
|
||||
|
||||
|
||||
+11
-2
@@ -16,6 +16,7 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
|
||||
private let roomProxy: JoinedRoomProxyProtocol
|
||||
private let mediaUploadingPreprocessor: MediaUploadingPreprocessor
|
||||
private let url: URL
|
||||
private let threadRootEventID: String?
|
||||
|
||||
private var processingTask: Task<Result<MediaInfo, MediaUploadingPreprocessorError>, Never>
|
||||
private var requestHandle: SendAttachmentJoinHandleProtocol?
|
||||
@@ -31,11 +32,13 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
|
||||
mediaUploadingPreprocessor: MediaUploadingPreprocessor,
|
||||
title: String?,
|
||||
url: URL,
|
||||
threadRootEventID: String?,
|
||||
shouldShowCaptionWarning: Bool) {
|
||||
self.userIndicatorController = userIndicatorController
|
||||
self.roomProxy = roomProxy
|
||||
self.mediaUploadingPreprocessor = mediaUploadingPreprocessor
|
||||
self.url = url
|
||||
self.threadRootEventID = threadRootEventID
|
||||
|
||||
// Start processing the media whilst the user is reviewing it/adding a caption.
|
||||
processingTask = Task { await mediaUploadingPreprocessor.processMedia(at: url) }
|
||||
@@ -57,7 +60,9 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
|
||||
Task {
|
||||
switch await processingTask.value {
|
||||
case .success(let mediaInfo):
|
||||
switch await sendAttachment(mediaInfo: mediaInfo, caption: caption) {
|
||||
switch await sendAttachment(mediaInfo: mediaInfo,
|
||||
caption: caption,
|
||||
threadRootEventID: threadRootEventID) {
|
||||
case .success:
|
||||
actionsSubject.send(.dismiss)
|
||||
case .failure(let error):
|
||||
@@ -85,7 +90,7 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
|
||||
|
||||
// MARK: - Private
|
||||
|
||||
private func sendAttachment(mediaInfo: MediaInfo, caption: String?) async -> Result<Void, TimelineProxyError> {
|
||||
private func sendAttachment(mediaInfo: MediaInfo, caption: String?, threadRootEventID: String?) async -> Result<Void, TimelineProxyError> {
|
||||
let requestHandle: ((SendAttachmentJoinHandleProtocol) -> Void) = { [weak self] handle in
|
||||
self?.requestHandle = handle
|
||||
}
|
||||
@@ -96,22 +101,26 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
|
||||
thumbnailURL: thumbnailURL,
|
||||
imageInfo: imageInfo,
|
||||
caption: caption,
|
||||
threadRootEventID: threadRootEventID,
|
||||
requestHandle: requestHandle)
|
||||
case let .video(videoURL, thumbnailURL, videoInfo):
|
||||
return await roomProxy.timeline.sendVideo(url: videoURL,
|
||||
thumbnailURL: thumbnailURL,
|
||||
videoInfo: videoInfo,
|
||||
caption: caption,
|
||||
threadRootEventID: threadRootEventID,
|
||||
requestHandle: requestHandle)
|
||||
case let .audio(audioURL, audioInfo):
|
||||
return await roomProxy.timeline.sendAudio(url: audioURL,
|
||||
audioInfo: audioInfo,
|
||||
caption: caption,
|
||||
threadRootEventID: threadRootEventID,
|
||||
requestHandle: requestHandle)
|
||||
case let .file(fileURL, fileInfo):
|
||||
return await roomProxy.timeline.sendFile(url: fileURL,
|
||||
fileInfo: fileInfo,
|
||||
caption: caption,
|
||||
threadRootEventID: threadRootEventID,
|
||||
requestHandle: requestHandle)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -232,6 +232,7 @@ struct MediaUploadPreviewScreen_Previews: PreviewProvider, TestablePreview {
|
||||
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: ServiceLocator.shared.settings),
|
||||
title: "App Icon.png",
|
||||
url: snapshotURL,
|
||||
threadRootEventID: nil,
|
||||
shouldShowCaptionWarning: true)
|
||||
static var previews: some View {
|
||||
NavigationStack {
|
||||
|
||||
@@ -80,6 +80,8 @@ struct ComposerToolbarViewState: BindableState {
|
||||
|
||||
var keyCommands: [WysiwygKeyCommand] = []
|
||||
|
||||
var isInThread: Bool
|
||||
|
||||
var bindings: ComposerToolbarViewStateBindings
|
||||
|
||||
var isUploading: Bool {
|
||||
|
||||
@@ -46,6 +46,7 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
|
||||
|
||||
init(initialText: String? = nil,
|
||||
roomProxy: JoinedRoomProxyProtocol,
|
||||
isInThread: Bool = false,
|
||||
wysiwygViewModel: WysiwygComposerViewModel,
|
||||
completionSuggestionService: CompletionSuggestionServiceProtocol,
|
||||
mediaProvider: MediaProviderProtocol,
|
||||
@@ -68,6 +69,7 @@ final class ComposerToolbarViewModel: ComposerToolbarViewModelType, ComposerTool
|
||||
audioRecorderState: .init(),
|
||||
isRoomEncrypted: roomProxy.infoPublisher.value.isEncrypted,
|
||||
isLocationSharingEnabled: appSettings.mapTilerConfiguration.isEnabled,
|
||||
isInThread: isInThread,
|
||||
bindings: .init()),
|
||||
mediaProvider: mediaProvider)
|
||||
|
||||
|
||||
@@ -40,14 +40,16 @@ struct RoomAttachmentPicker: View {
|
||||
}
|
||||
.accessibilityIdentifier(A11yIdentifiers.roomScreen.attachmentPickerTextFormatting)
|
||||
|
||||
Button {
|
||||
context.send(viewAction: .attach(.poll))
|
||||
} label: {
|
||||
Label(L10n.screenRoomAttachmentSourcePoll, icon: \.polls)
|
||||
if !context.viewState.isInThread {
|
||||
Button {
|
||||
context.send(viewAction: .attach(.poll))
|
||||
} label: {
|
||||
Label(L10n.screenRoomAttachmentSourcePoll, icon: \.polls)
|
||||
}
|
||||
.accessibilityIdentifier(A11yIdentifiers.roomScreen.attachmentPickerPoll)
|
||||
}
|
||||
.accessibilityIdentifier(A11yIdentifiers.roomScreen.attachmentPickerPoll)
|
||||
|
||||
if context.viewState.isLocationSharingEnabled {
|
||||
if !context.viewState.isInThread, context.viewState.isLocationSharingEnabled {
|
||||
Button {
|
||||
context.send(viewAction: .attach(.location))
|
||||
} label: {
|
||||
|
||||
@@ -98,6 +98,7 @@ final class RoomScreenCoordinator: CoordinatorProtocol {
|
||||
parserStyle: .elementX)
|
||||
let composerViewModel = ComposerToolbarViewModel(initialText: parameters.sharedText,
|
||||
roomProxy: parameters.roomProxy,
|
||||
isInThread: false,
|
||||
wysiwygViewModel: wysiwygViewModel,
|
||||
completionSuggestionService: parameters.completionSuggestionService,
|
||||
mediaProvider: parameters.mediaProvider,
|
||||
|
||||
@@ -27,8 +27,8 @@ struct ThreadTimelineScreenCoordinatorParameters {
|
||||
|
||||
enum ThreadTimelineScreenCoordinatorAction {
|
||||
case presentReportContent(itemID: TimelineItemIdentifier, senderID: String)
|
||||
case presentMediaUploadPicker(MediaPickerScreenSource)
|
||||
case presentMediaUploadPreviewScreen(URL)
|
||||
case presentMediaUploadPicker(MediaPickerScreenSource, threadRootEventID: String?)
|
||||
case presentMediaUploadPreviewScreen(url: URL, threadRootEventID: String?)
|
||||
case presentLocationPicker
|
||||
case presentPollForm(mode: PollFormMode)
|
||||
case presentLocationViewer(body: String, geoURI: GeoURI, description: String?)
|
||||
@@ -78,6 +78,7 @@ final class ThreadTimelineScreenCoordinator: CoordinatorProtocol {
|
||||
|
||||
composerViewModel = ComposerToolbarViewModel(initialText: nil,
|
||||
roomProxy: parameters.roomProxy,
|
||||
isInThread: true,
|
||||
wysiwygViewModel: wysiwygViewModel,
|
||||
completionSuggestionService: parameters.completionSuggestionService,
|
||||
mediaProvider: parameters.mediaProvider,
|
||||
@@ -98,11 +99,11 @@ final class ThreadTimelineScreenCoordinator: CoordinatorProtocol {
|
||||
case .displayReportContent(let itemID, let senderID):
|
||||
actionsSubject.send(.presentReportContent(itemID: itemID, senderID: senderID))
|
||||
case .displayCameraPicker:
|
||||
actionsSubject.send(.presentMediaUploadPicker(.camera))
|
||||
actionsSubject.send(.presentMediaUploadPicker(.camera, threadRootEventID: parameters.timelineController.timelineKind.threadRootEventID))
|
||||
case .displayMediaPicker:
|
||||
actionsSubject.send(.presentMediaUploadPicker(.photoLibrary))
|
||||
actionsSubject.send(.presentMediaUploadPicker(.photoLibrary, threadRootEventID: parameters.timelineController.timelineKind.threadRootEventID))
|
||||
case .displayDocumentPicker:
|
||||
actionsSubject.send(.presentMediaUploadPicker(.documents))
|
||||
actionsSubject.send(.presentMediaUploadPicker(.documents, threadRootEventID: parameters.timelineController.timelineKind.threadRootEventID))
|
||||
case .displayMediaPreview(let mediaPreviewViewModel):
|
||||
viewModel.displayMediaPreview(mediaPreviewViewModel)
|
||||
case .displayLocationPicker:
|
||||
@@ -110,7 +111,7 @@ final class ThreadTimelineScreenCoordinator: CoordinatorProtocol {
|
||||
case .displayPollForm(let mode):
|
||||
actionsSubject.send(.presentPollForm(mode: mode))
|
||||
case .displayMediaUploadPreviewScreen(let url):
|
||||
actionsSubject.send(.presentMediaUploadPreviewScreen(url))
|
||||
actionsSubject.send(.presentMediaUploadPreviewScreen(url: url, threadRootEventID: parameters.timelineController.timelineKind.threadRootEventID))
|
||||
case .displaySenderDetails(userID: let userID):
|
||||
actionsSubject.send(.presentRoomMemberDetails(userID: userID))
|
||||
case .displayMessageForwarding(let forwardingItem):
|
||||
|
||||
@@ -362,7 +362,9 @@ class TimelineInteractionHandler {
|
||||
|
||||
actionsSubject.send(.composer(action: .setMode(mode: .previewVoiceMessage(state: audioPlayerState, waveform: .url(recordingURL), isUploading: true))))
|
||||
await voiceMessageRecorder.stopPlayback()
|
||||
switch await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy, audioConverter: AudioConverter()) {
|
||||
switch await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy,
|
||||
audioConverter: AudioConverter(),
|
||||
threadRootEventID: timelineController.timelineKind.threadRootEventID) {
|
||||
case .success:
|
||||
await deleteCurrentVoiceMessage()
|
||||
case .failure(let error):
|
||||
|
||||
@@ -229,15 +229,22 @@ final class TimelineProxy: TimelineProxyProtocol {
|
||||
func sendAudio(url: URL,
|
||||
audioInfo: AudioInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
MXLog.info("Sending audio")
|
||||
|
||||
let replyParameters: ReplyParameters? = if let threadRootEventID {
|
||||
ReplyParameters(eventId: threadRootEventID, enforceThread: true, replyWithinThread: false)
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
|
||||
do {
|
||||
let handle = try timeline.sendAudio(params: .init(source: .file(filename: url.path(percentEncoded: false)),
|
||||
caption: caption,
|
||||
formattedCaption: nil, // Rust will build this from the caption's markdown.
|
||||
mentions: nil,
|
||||
replyParams: nil,
|
||||
replyParams: replyParameters,
|
||||
useSendQueue: true),
|
||||
audioInfo: audioInfo,
|
||||
progressWatcher: nil)
|
||||
@@ -257,15 +264,22 @@ final class TimelineProxy: TimelineProxyProtocol {
|
||||
func sendFile(url: URL,
|
||||
fileInfo: FileInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
MXLog.info("Sending file")
|
||||
|
||||
let replyParameters: ReplyParameters? = if let threadRootEventID {
|
||||
ReplyParameters(eventId: threadRootEventID, enforceThread: true, replyWithinThread: false)
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
|
||||
do {
|
||||
let handle = try timeline.sendFile(params: .init(source: .file(filename: url.path(percentEncoded: false)),
|
||||
caption: caption,
|
||||
formattedCaption: nil, // Rust will build this from the caption's markdown.
|
||||
mentions: nil,
|
||||
replyParams: nil,
|
||||
replyParams: replyParameters,
|
||||
useSendQueue: true),
|
||||
fileInfo: fileInfo,
|
||||
progressWatcher: nil)
|
||||
@@ -286,15 +300,22 @@ final class TimelineProxy: TimelineProxyProtocol {
|
||||
thumbnailURL: URL,
|
||||
imageInfo: ImageInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
MXLog.info("Sending image")
|
||||
|
||||
let replyParameters: ReplyParameters? = if let threadRootEventID {
|
||||
ReplyParameters(eventId: threadRootEventID, enforceThread: true, replyWithinThread: false)
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
|
||||
do {
|
||||
let handle = try timeline.sendImage(params: .init(source: .file(filename: url.path(percentEncoded: false)),
|
||||
caption: caption,
|
||||
formattedCaption: nil, // Rust will build this from the caption's markdown.
|
||||
mentions: nil,
|
||||
replyParams: nil,
|
||||
replyParams: replyParameters,
|
||||
useSendQueue: true),
|
||||
thumbnailPath: thumbnailURL.path(percentEncoded: false),
|
||||
imageInfo: imageInfo,
|
||||
@@ -316,7 +337,8 @@ final class TimelineProxy: TimelineProxyProtocol {
|
||||
geoURI: GeoURI,
|
||||
description: String?,
|
||||
zoomLevel: UInt8?,
|
||||
assetType: AssetType?) async -> Result<Void, TimelineProxyError> {
|
||||
assetType: AssetType?,
|
||||
threadRootEventID: String?) async -> Result<Void, TimelineProxyError> {
|
||||
MXLog.info("Sending location")
|
||||
|
||||
await timeline.sendLocation(body: body,
|
||||
@@ -334,15 +356,22 @@ final class TimelineProxy: TimelineProxyProtocol {
|
||||
thumbnailURL: URL,
|
||||
videoInfo: VideoInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
MXLog.info("Sending video")
|
||||
|
||||
let replyParameters: ReplyParameters? = if let threadRootEventID {
|
||||
ReplyParameters(eventId: threadRootEventID, enforceThread: true, replyWithinThread: false)
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
|
||||
do {
|
||||
let handle = try timeline.sendVideo(params: .init(source: .file(filename: url.path(percentEncoded: false)),
|
||||
caption: caption,
|
||||
formattedCaption: nil,
|
||||
mentions: nil,
|
||||
replyParams: nil,
|
||||
replyParams: replyParameters,
|
||||
useSendQueue: true),
|
||||
thumbnailPath: thumbnailURL.path(percentEncoded: false),
|
||||
videoInfo: videoInfo,
|
||||
@@ -363,15 +392,22 @@ final class TimelineProxy: TimelineProxyProtocol {
|
||||
func sendVoiceMessage(url: URL,
|
||||
audioInfo: AudioInfo,
|
||||
waveform: [UInt16],
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError> {
|
||||
MXLog.info("Sending voice message")
|
||||
|
||||
let replyParameters: ReplyParameters? = if let threadRootEventID {
|
||||
ReplyParameters(eventId: threadRootEventID, enforceThread: true, replyWithinThread: false)
|
||||
} else {
|
||||
nil
|
||||
}
|
||||
|
||||
do {
|
||||
let handle = try timeline.sendVoiceMessage(params: .init(source: .file(filename: url.path(percentEncoded: false)),
|
||||
caption: nil,
|
||||
formattedCaption: nil,
|
||||
mentions: nil,
|
||||
replyParams: nil,
|
||||
replyParams: replyParameters,
|
||||
useSendQueue: true),
|
||||
audioInfo: audioInfo,
|
||||
waveform: waveform,
|
||||
@@ -481,7 +517,9 @@ final class TimelineProxy: TimelineProxyProtocol {
|
||||
|
||||
// MARK: - Polls
|
||||
|
||||
func createPoll(question: String, answers: [String], pollKind: Poll.Kind) async -> Result<Void, TimelineProxyError> {
|
||||
func createPoll(question: String, answers: [String],
|
||||
pollKind: Poll.Kind,
|
||||
threadRootEventID: String? = nil) async -> Result<Void, TimelineProxyError> {
|
||||
MXLog.info("Creating poll")
|
||||
|
||||
do {
|
||||
|
||||
@@ -82,34 +82,40 @@ protocol TimelineProxyProtocol {
|
||||
func sendAudio(url: URL,
|
||||
audioInfo: AudioInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>
|
||||
|
||||
func sendFile(url: URL,
|
||||
fileInfo: FileInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>
|
||||
|
||||
func sendImage(url: URL,
|
||||
thumbnailURL: URL,
|
||||
imageInfo: ImageInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>
|
||||
|
||||
func sendLocation(body: String,
|
||||
geoURI: GeoURI,
|
||||
description: String?,
|
||||
zoomLevel: UInt8?,
|
||||
assetType: AssetType?) async -> Result<Void, TimelineProxyError>
|
||||
assetType: AssetType?,
|
||||
threadRootEventID: String?) async -> Result<Void, TimelineProxyError>
|
||||
|
||||
func sendVideo(url: URL,
|
||||
thumbnailURL: URL,
|
||||
videoInfo: VideoInfo,
|
||||
caption: String?,
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>
|
||||
|
||||
func sendVoiceMessage(url: URL,
|
||||
audioInfo: AudioInfo,
|
||||
waveform: [UInt16],
|
||||
threadRootEventID: String?,
|
||||
requestHandle: @MainActor (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, TimelineProxyError>
|
||||
|
||||
func sendReadReceipt(for eventID: String, type: ReceiptType) async -> Result<Void, TimelineProxyError>
|
||||
@@ -124,7 +130,7 @@ protocol TimelineProxyProtocol {
|
||||
|
||||
func toggleReaction(_ reaction: String, to eventID: TimelineItemIdentifier.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, threadRootEventID: String?) async -> Result<Void, TimelineProxyError>
|
||||
|
||||
func editPoll(original eventID: String,
|
||||
question: String,
|
||||
|
||||
@@ -144,7 +144,9 @@ class VoiceMessageRecorder: VoiceMessageRecorderProtocol {
|
||||
return .success(waveformData)
|
||||
}
|
||||
|
||||
func sendVoiceMessage(inRoom roomProxy: JoinedRoomProxyProtocol, audioConverter: AudioConverterProtocol) async -> Result<Void, VoiceMessageRecorderError> {
|
||||
func sendVoiceMessage(inRoom roomProxy: JoinedRoomProxyProtocol,
|
||||
audioConverter: AudioConverterProtocol,
|
||||
threadRootEventID: String?) async -> Result<Void, VoiceMessageRecorderError> {
|
||||
guard let url = audioRecorder.audioFileURL else {
|
||||
return .failure(VoiceMessageRecorderError.missingRecordingFile)
|
||||
}
|
||||
@@ -178,7 +180,8 @@ class VoiceMessageRecorder: VoiceMessageRecorderProtocol {
|
||||
|
||||
let result = await roomProxy.timeline.sendVoiceMessage(url: oggFile,
|
||||
audioInfo: audioInfo,
|
||||
waveform: waveform) { _ in }
|
||||
waveform: waveform,
|
||||
threadRootEventID: threadRootEventID) { _ in }
|
||||
|
||||
if case .failure(let error) = result {
|
||||
MXLog.error("Failed to send the voice message. \(error)")
|
||||
|
||||
@@ -38,7 +38,9 @@ protocol VoiceMessageRecorderProtocol {
|
||||
func seekPlayback(to progress: Double) async
|
||||
func deleteRecording() async
|
||||
|
||||
func sendVoiceMessage(inRoom roomProxy: JoinedRoomProxyProtocol, audioConverter: AudioConverterProtocol) async -> Result<Void, VoiceMessageRecorderError>
|
||||
func sendVoiceMessage(inRoom roomProxy: JoinedRoomProxyProtocol,
|
||||
audioConverter: AudioConverterProtocol,
|
||||
threadRootEventID: String?) async -> Result<Void, VoiceMessageRecorderError>
|
||||
}
|
||||
|
||||
// sourcery: AutoMockable
|
||||
|
||||
@@ -106,16 +106,16 @@ class MediaUploadPreviewScreenViewModelTests: XCTestCase {
|
||||
|
||||
private func setUpViewModel(url: URL, expectedCaption: String?) {
|
||||
timelineProxy = TimelineProxyMock(.init())
|
||||
timelineProxy.sendAudioUrlAudioInfoCaptionRequestHandleClosure = { [weak self] _, _, caption, _ in
|
||||
timelineProxy.sendAudioUrlAudioInfoCaptionThreadRootEventIDRequestHandleClosure = { [weak self] _, _, caption, _, _ in
|
||||
self?.verifyCaption(caption, expectedCaption: expectedCaption) ?? .failure(.sdkError(TestError.unknown))
|
||||
}
|
||||
timelineProxy.sendFileUrlFileInfoCaptionRequestHandleClosure = { [weak self] _, _, caption, _ in
|
||||
timelineProxy.sendFileUrlFileInfoCaptionThreadRootEventIDRequestHandleClosure = { [weak self] _, _, caption, _, _ in
|
||||
self?.verifyCaption(caption, expectedCaption: expectedCaption) ?? .failure(.sdkError(TestError.unknown))
|
||||
}
|
||||
timelineProxy.sendImageUrlThumbnailURLImageInfoCaptionRequestHandleClosure = { [weak self] _, _, _, caption, _ in
|
||||
timelineProxy.sendImageUrlThumbnailURLImageInfoCaptionThreadRootEventIDRequestHandleClosure = { [weak self] _, _, _, caption, _, _ in
|
||||
self?.verifyCaption(caption, expectedCaption: expectedCaption) ?? .failure(.sdkError(TestError.unknown))
|
||||
}
|
||||
timelineProxy.sendVideoUrlThumbnailURLVideoInfoCaptionRequestHandleClosure = { [weak self] _, _, _, caption, _ in
|
||||
timelineProxy.sendVideoUrlThumbnailURLVideoInfoCaptionThreadRootEventIDRequestHandleClosure = { [weak self] _, _, _, caption, _, _ in
|
||||
self?.verifyCaption(caption, expectedCaption: expectedCaption) ?? .failure(.sdkError(TestError.unknown))
|
||||
}
|
||||
|
||||
@@ -126,6 +126,7 @@ class MediaUploadPreviewScreenViewModelTests: XCTestCase {
|
||||
mediaUploadingPreprocessor: MediaUploadingPreprocessor(appSettings: ServiceLocator.shared.settings),
|
||||
title: "Some File",
|
||||
url: url,
|
||||
threadRootEventID: nil,
|
||||
shouldShowCaptionWarning: true)
|
||||
}
|
||||
|
||||
|
||||
@@ -196,7 +196,9 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
|
||||
// If there is no recording file, an error is expected
|
||||
audioRecorder.audioFileURL = nil
|
||||
guard case .failure(.missingRecordingFile) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy, audioConverter: audioConverter) else {
|
||||
guard case .failure(.missingRecordingFile) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy,
|
||||
audioConverter: audioConverter,
|
||||
threadRootEventID: nil) else {
|
||||
XCTFail("An error is expected")
|
||||
return
|
||||
}
|
||||
@@ -208,7 +210,9 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
audioConverter.convertToOpusOggSourceURLDestinationURLThrowableError = AudioConverterError.conversionFailed(nil)
|
||||
|
||||
let roomProxy = JoinedRoomProxyMock()
|
||||
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy, audioConverter: audioConverter) else {
|
||||
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy,
|
||||
audioConverter: audioConverter,
|
||||
threadRootEventID: nil) else {
|
||||
XCTFail("An error is expected")
|
||||
return
|
||||
}
|
||||
@@ -227,8 +231,10 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
let timelineProxy = TimelineProxyMock()
|
||||
let roomProxy = JoinedRoomProxyMock()
|
||||
roomProxy.timeline = timelineProxy
|
||||
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformRequestHandleReturnValue = .failure(.sdkError(SDKError.generic))
|
||||
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy, audioConverter: audioConverter) else {
|
||||
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleReturnValue = .failure(.sdkError(SDKError.generic))
|
||||
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy,
|
||||
audioConverter: audioConverter,
|
||||
threadRootEventID: nil) else {
|
||||
XCTFail("An error is expected")
|
||||
return
|
||||
}
|
||||
@@ -248,8 +254,10 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
let timelineProxy = TimelineProxyMock()
|
||||
let roomProxy = JoinedRoomProxyMock()
|
||||
roomProxy.timeline = timelineProxy
|
||||
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformRequestHandleReturnValue = .failure(.sdkError(SDKError.generic))
|
||||
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy, audioConverter: audioConverter) else {
|
||||
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleReturnValue = .failure(.sdkError(SDKError.generic))
|
||||
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy,
|
||||
audioConverter: audioConverter,
|
||||
threadRootEventID: nil) else {
|
||||
XCTFail("An error is expected")
|
||||
return
|
||||
}
|
||||
@@ -271,8 +279,10 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
let timelineProxy = TimelineProxyMock()
|
||||
let roomProxy = JoinedRoomProxyMock()
|
||||
roomProxy.timeline = timelineProxy
|
||||
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformRequestHandleReturnValue = .failure(.sdkError(SDKError.generic))
|
||||
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy, audioConverter: audioConverter) else {
|
||||
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleReturnValue = .failure(.sdkError(SDKError.generic))
|
||||
guard case .failure(.failedSendingVoiceMessage) = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy,
|
||||
audioConverter: audioConverter,
|
||||
threadRootEventID: nil) else {
|
||||
XCTFail("An error is expected")
|
||||
return
|
||||
}
|
||||
@@ -307,7 +317,7 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
XCTAssertEqual(destination.pathExtension, "ogg")
|
||||
}
|
||||
|
||||
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformRequestHandleClosure = { url, audioInfo, waveform, _ in
|
||||
timelineProxy.sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleClosure = { url, audioInfo, waveform, _, _ in
|
||||
XCTAssertEqual(url, convertedFileURL)
|
||||
XCTAssertEqual(audioInfo.duration, self.audioRecorder.currentTime)
|
||||
XCTAssertEqual(audioInfo.size, convertedFileSize)
|
||||
@@ -317,13 +327,13 @@ class VoiceMessageRecorderTests: XCTestCase {
|
||||
return .success(())
|
||||
}
|
||||
|
||||
guard case .success = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy, audioConverter: audioConverter) else {
|
||||
guard case .success = await voiceMessageRecorder.sendVoiceMessage(inRoom: roomProxy, audioConverter: audioConverter, threadRootEventID: nil) else {
|
||||
XCTFail("A success is expected")
|
||||
return
|
||||
}
|
||||
|
||||
XCTAssert(audioConverter.convertToOpusOggSourceURLDestinationURLCalled)
|
||||
XCTAssert(timelineProxy.sendVoiceMessageUrlAudioInfoWaveformRequestHandleCalled)
|
||||
XCTAssert(timelineProxy.sendVoiceMessageUrlAudioInfoWaveformThreadRootEventIDRequestHandleCalled)
|
||||
|
||||
// the converted file must have been deleted
|
||||
if let convertedFileURL {
|
||||
|
||||
Reference in New Issue
Block a user