Fixes #954 - Implement media upload cancelling

This commit is contained in:
Stefan Ceriu
2023-06-28 14:59:57 +03:00
committed by Stefan Ceriu
parent d9e608a1e0
commit ce7ca32efc
17 changed files with 184 additions and 128 deletions
+1 -1
View File
@@ -5099,7 +5099,7 @@
repositoryURL = "https://github.com/matrix-org/matrix-rust-components-swift"; repositoryURL = "https://github.com/matrix-org/matrix-rust-components-swift";
requirement = { requirement = {
kind = exactVersion; kind = exactVersion;
version = "1.0.89-alpha"; version = "1.0.91-alpha";
}; };
}; };
96495DD8554E2F39D3954354 /* XCRemoteSwiftPackageReference "posthog-ios" */ = { 96495DD8554E2F39D3954354 /* XCRemoteSwiftPackageReference "posthog-ios" */ = {
@@ -111,8 +111,8 @@
"kind" : "remoteSourceControl", "kind" : "remoteSourceControl",
"location" : "https://github.com/matrix-org/matrix-rust-components-swift", "location" : "https://github.com/matrix-org/matrix-rust-components-swift",
"state" : { "state" : {
"revision" : "2f649822e3ce6d2a6b502602c0ab10e67f820bb5", "revision" : "51c57a8c6c0d05fcaa249226e8e2a9df6e21e7cf",
"version" : "1.0.89-alpha" "version" : "1.0.91-alpha"
} }
}, },
{ {
@@ -637,86 +637,70 @@ class RoomProxyMock: RoomProxyProtocol {
} }
//MARK: - sendImage //MARK: - sendImage
var sendImageUrlThumbnailURLImageInfoProgressSubjectCallsCount = 0 var sendImageUrlThumbnailURLImageInfoProgressSubjectRequestHandleCallsCount = 0
var sendImageUrlThumbnailURLImageInfoProgressSubjectCalled: Bool { var sendImageUrlThumbnailURLImageInfoProgressSubjectRequestHandleCalled: Bool {
return sendImageUrlThumbnailURLImageInfoProgressSubjectCallsCount > 0 return sendImageUrlThumbnailURLImageInfoProgressSubjectRequestHandleCallsCount > 0
} }
var sendImageUrlThumbnailURLImageInfoProgressSubjectReceivedArguments: (url: URL, thumbnailURL: URL, imageInfo: ImageInfo, progressSubject: CurrentValueSubject<Double, Never>?)? var sendImageUrlThumbnailURLImageInfoProgressSubjectRequestHandleReturnValue: Result<Void, RoomProxyError>!
var sendImageUrlThumbnailURLImageInfoProgressSubjectReceivedInvocations: [(url: URL, thumbnailURL: URL, imageInfo: ImageInfo, progressSubject: CurrentValueSubject<Double, Never>?)] = [] var sendImageUrlThumbnailURLImageInfoProgressSubjectRequestHandleClosure: ((URL, URL, ImageInfo, CurrentValueSubject<Double, Never>?, (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError>)?
var sendImageUrlThumbnailURLImageInfoProgressSubjectReturnValue: Result<Void, RoomProxyError>!
var sendImageUrlThumbnailURLImageInfoProgressSubjectClosure: ((URL, URL, ImageInfo, CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError>)?
func sendImage(url: URL, thumbnailURL: URL, imageInfo: ImageInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> { func sendImage(url: URL, thumbnailURL: URL, imageInfo: ImageInfo, progressSubject: CurrentValueSubject<Double, Never>?, requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> {
sendImageUrlThumbnailURLImageInfoProgressSubjectCallsCount += 1 sendImageUrlThumbnailURLImageInfoProgressSubjectRequestHandleCallsCount += 1
sendImageUrlThumbnailURLImageInfoProgressSubjectReceivedArguments = (url: url, thumbnailURL: thumbnailURL, imageInfo: imageInfo, progressSubject: progressSubject) if let sendImageUrlThumbnailURLImageInfoProgressSubjectRequestHandleClosure = sendImageUrlThumbnailURLImageInfoProgressSubjectRequestHandleClosure {
sendImageUrlThumbnailURLImageInfoProgressSubjectReceivedInvocations.append((url: url, thumbnailURL: thumbnailURL, imageInfo: imageInfo, progressSubject: progressSubject)) return await sendImageUrlThumbnailURLImageInfoProgressSubjectRequestHandleClosure(url, thumbnailURL, imageInfo, progressSubject, requestHandle)
if let sendImageUrlThumbnailURLImageInfoProgressSubjectClosure = sendImageUrlThumbnailURLImageInfoProgressSubjectClosure {
return await sendImageUrlThumbnailURLImageInfoProgressSubjectClosure(url, thumbnailURL, imageInfo, progressSubject)
} else { } else {
return sendImageUrlThumbnailURLImageInfoProgressSubjectReturnValue return sendImageUrlThumbnailURLImageInfoProgressSubjectRequestHandleReturnValue
} }
} }
//MARK: - sendVideo //MARK: - sendVideo
var sendVideoUrlThumbnailURLVideoInfoProgressSubjectCallsCount = 0 var sendVideoUrlThumbnailURLVideoInfoProgressSubjectRequestHandleCallsCount = 0
var sendVideoUrlThumbnailURLVideoInfoProgressSubjectCalled: Bool { var sendVideoUrlThumbnailURLVideoInfoProgressSubjectRequestHandleCalled: Bool {
return sendVideoUrlThumbnailURLVideoInfoProgressSubjectCallsCount > 0 return sendVideoUrlThumbnailURLVideoInfoProgressSubjectRequestHandleCallsCount > 0
} }
var sendVideoUrlThumbnailURLVideoInfoProgressSubjectReceivedArguments: (url: URL, thumbnailURL: URL, videoInfo: VideoInfo, progressSubject: CurrentValueSubject<Double, Never>?)? var sendVideoUrlThumbnailURLVideoInfoProgressSubjectRequestHandleReturnValue: Result<Void, RoomProxyError>!
var sendVideoUrlThumbnailURLVideoInfoProgressSubjectReceivedInvocations: [(url: URL, thumbnailURL: URL, videoInfo: VideoInfo, progressSubject: CurrentValueSubject<Double, Never>?)] = [] var sendVideoUrlThumbnailURLVideoInfoProgressSubjectRequestHandleClosure: ((URL, URL, VideoInfo, CurrentValueSubject<Double, Never>?, (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError>)?
var sendVideoUrlThumbnailURLVideoInfoProgressSubjectReturnValue: Result<Void, RoomProxyError>!
var sendVideoUrlThumbnailURLVideoInfoProgressSubjectClosure: ((URL, URL, VideoInfo, CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError>)?
func sendVideo(url: URL, thumbnailURL: URL, videoInfo: VideoInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> { func sendVideo(url: URL, thumbnailURL: URL, videoInfo: VideoInfo, progressSubject: CurrentValueSubject<Double, Never>?, requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> {
sendVideoUrlThumbnailURLVideoInfoProgressSubjectCallsCount += 1 sendVideoUrlThumbnailURLVideoInfoProgressSubjectRequestHandleCallsCount += 1
sendVideoUrlThumbnailURLVideoInfoProgressSubjectReceivedArguments = (url: url, thumbnailURL: thumbnailURL, videoInfo: videoInfo, progressSubject: progressSubject) if let sendVideoUrlThumbnailURLVideoInfoProgressSubjectRequestHandleClosure = sendVideoUrlThumbnailURLVideoInfoProgressSubjectRequestHandleClosure {
sendVideoUrlThumbnailURLVideoInfoProgressSubjectReceivedInvocations.append((url: url, thumbnailURL: thumbnailURL, videoInfo: videoInfo, progressSubject: progressSubject)) return await sendVideoUrlThumbnailURLVideoInfoProgressSubjectRequestHandleClosure(url, thumbnailURL, videoInfo, progressSubject, requestHandle)
if let sendVideoUrlThumbnailURLVideoInfoProgressSubjectClosure = sendVideoUrlThumbnailURLVideoInfoProgressSubjectClosure {
return await sendVideoUrlThumbnailURLVideoInfoProgressSubjectClosure(url, thumbnailURL, videoInfo, progressSubject)
} else { } else {
return sendVideoUrlThumbnailURLVideoInfoProgressSubjectReturnValue return sendVideoUrlThumbnailURLVideoInfoProgressSubjectRequestHandleReturnValue
} }
} }
//MARK: - sendAudio //MARK: - sendAudio
var sendAudioUrlAudioInfoProgressSubjectCallsCount = 0 var sendAudioUrlAudioInfoProgressSubjectRequestHandleCallsCount = 0
var sendAudioUrlAudioInfoProgressSubjectCalled: Bool { var sendAudioUrlAudioInfoProgressSubjectRequestHandleCalled: Bool {
return sendAudioUrlAudioInfoProgressSubjectCallsCount > 0 return sendAudioUrlAudioInfoProgressSubjectRequestHandleCallsCount > 0
} }
var sendAudioUrlAudioInfoProgressSubjectReceivedArguments: (url: URL, audioInfo: AudioInfo, progressSubject: CurrentValueSubject<Double, Never>?)? var sendAudioUrlAudioInfoProgressSubjectRequestHandleReturnValue: Result<Void, RoomProxyError>!
var sendAudioUrlAudioInfoProgressSubjectReceivedInvocations: [(url: URL, audioInfo: AudioInfo, progressSubject: CurrentValueSubject<Double, Never>?)] = [] var sendAudioUrlAudioInfoProgressSubjectRequestHandleClosure: ((URL, AudioInfo, CurrentValueSubject<Double, Never>?, (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError>)?
var sendAudioUrlAudioInfoProgressSubjectReturnValue: Result<Void, RoomProxyError>!
var sendAudioUrlAudioInfoProgressSubjectClosure: ((URL, AudioInfo, CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError>)?
func sendAudio(url: URL, audioInfo: AudioInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> { func sendAudio(url: URL, audioInfo: AudioInfo, progressSubject: CurrentValueSubject<Double, Never>?, requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> {
sendAudioUrlAudioInfoProgressSubjectCallsCount += 1 sendAudioUrlAudioInfoProgressSubjectRequestHandleCallsCount += 1
sendAudioUrlAudioInfoProgressSubjectReceivedArguments = (url: url, audioInfo: audioInfo, progressSubject: progressSubject) if let sendAudioUrlAudioInfoProgressSubjectRequestHandleClosure = sendAudioUrlAudioInfoProgressSubjectRequestHandleClosure {
sendAudioUrlAudioInfoProgressSubjectReceivedInvocations.append((url: url, audioInfo: audioInfo, progressSubject: progressSubject)) return await sendAudioUrlAudioInfoProgressSubjectRequestHandleClosure(url, audioInfo, progressSubject, requestHandle)
if let sendAudioUrlAudioInfoProgressSubjectClosure = sendAudioUrlAudioInfoProgressSubjectClosure {
return await sendAudioUrlAudioInfoProgressSubjectClosure(url, audioInfo, progressSubject)
} else { } else {
return sendAudioUrlAudioInfoProgressSubjectReturnValue return sendAudioUrlAudioInfoProgressSubjectRequestHandleReturnValue
} }
} }
//MARK: - sendFile //MARK: - sendFile
var sendFileUrlFileInfoProgressSubjectCallsCount = 0 var sendFileUrlFileInfoProgressSubjectRequestHandleCallsCount = 0
var sendFileUrlFileInfoProgressSubjectCalled: Bool { var sendFileUrlFileInfoProgressSubjectRequestHandleCalled: Bool {
return sendFileUrlFileInfoProgressSubjectCallsCount > 0 return sendFileUrlFileInfoProgressSubjectRequestHandleCallsCount > 0
} }
var sendFileUrlFileInfoProgressSubjectReceivedArguments: (url: URL, fileInfo: FileInfo, progressSubject: CurrentValueSubject<Double, Never>?)? var sendFileUrlFileInfoProgressSubjectRequestHandleReturnValue: Result<Void, RoomProxyError>!
var sendFileUrlFileInfoProgressSubjectReceivedInvocations: [(url: URL, fileInfo: FileInfo, progressSubject: CurrentValueSubject<Double, Never>?)] = [] var sendFileUrlFileInfoProgressSubjectRequestHandleClosure: ((URL, FileInfo, CurrentValueSubject<Double, Never>?, (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError>)?
var sendFileUrlFileInfoProgressSubjectReturnValue: Result<Void, RoomProxyError>!
var sendFileUrlFileInfoProgressSubjectClosure: ((URL, FileInfo, CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError>)?
func sendFile(url: URL, fileInfo: FileInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> { func sendFile(url: URL, fileInfo: FileInfo, progressSubject: CurrentValueSubject<Double, Never>?, requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> {
sendFileUrlFileInfoProgressSubjectCallsCount += 1 sendFileUrlFileInfoProgressSubjectRequestHandleCallsCount += 1
sendFileUrlFileInfoProgressSubjectReceivedArguments = (url: url, fileInfo: fileInfo, progressSubject: progressSubject) if let sendFileUrlFileInfoProgressSubjectRequestHandleClosure = sendFileUrlFileInfoProgressSubjectRequestHandleClosure {
sendFileUrlFileInfoProgressSubjectReceivedInvocations.append((url: url, fileInfo: fileInfo, progressSubject: progressSubject)) return await sendFileUrlFileInfoProgressSubjectRequestHandleClosure(url, fileInfo, progressSubject, requestHandle)
if let sendFileUrlFileInfoProgressSubjectClosure = sendFileUrlFileInfoProgressSubjectClosure {
return await sendFileUrlFileInfoProgressSubjectClosure(url, fileInfo, progressSubject)
} else { } else {
return sendFileUrlFileInfoProgressSubjectReturnValue return sendFileUrlFileInfoProgressSubjectRequestHandleReturnValue
} }
} }
//MARK: - sendLocation //MARK: - sendLocation
@@ -19,10 +19,10 @@ import Foundation
enum UserIndicatorType: Equatable { enum UserIndicatorType: Equatable {
case toast(progress: UserIndicator.Progress?) case toast(progress: UserIndicator.Progress?)
case modal(progress: UserIndicator.Progress?, interactiveDismissDisabled: Bool) case modal(progress: UserIndicator.Progress?, interactiveDismissDisabled: Bool, allowsInteraction: Bool)
static var toast: Self { .toast(progress: .none) } static var toast: Self { .toast(progress: .none) }
static var modal: Self { .modal(progress: .indeterminate, interactiveDismissDisabled: false) } static var modal: Self { .modal(progress: .indeterminate, interactiveDismissDisabled: false, allowsInteraction: false) }
} }
struct UserIndicator: Equatable, Identifiable { struct UserIndicator: Equatable, Identifiable {
@@ -50,13 +50,13 @@ struct UserIndicator: Equatable, Identifiable {
var progress: Progress? { var progress: Progress? {
switch type { switch type {
case .toast(let progress): return progress case .toast(let progress): return progress
case .modal(let progress, _): return progress case .modal(let progress, _, _): return progress
} }
} }
var progressPublisher: CurrentValuePublisher<Double, Never> { var progressPublisher: CurrentValuePublisher<Double, Never> {
switch type { switch type {
case .toast(let progress), .modal(let progress, _): case .toast(let progress), .modal(let progress, _, _):
switch progress { switch progress {
case .none, .indeterminate: case .none, .indeterminate:
return CurrentValueSubject<Double, Never>(0.0).asCurrentValuePublisher() return CurrentValueSubject<Double, Never>(0.0).asCurrentValuePublisher()
@@ -70,8 +70,17 @@ struct UserIndicator: Equatable, Identifiable {
switch type { switch type {
case .toast: case .toast:
return false return false
case .modal(_, let interactiveDismissDisabled): case .modal(_, let interactiveDismissDisabled, _):
return interactiveDismissDisabled return interactiveDismissDisabled
} }
} }
var allowsInteraction: Bool {
switch type {
case .toast:
return true
case .modal(_, _, let allowsInteraction):
return allowsInteraction
}
}
} }
@@ -54,7 +54,11 @@ struct UserIndicatorModalView: View {
} }
.id(indicator.id) .id(indicator.id)
.frame(maxWidth: .infinity, maxHeight: .infinity) .frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.black.opacity(0.1)) .background {
if !indicator.allowsInteraction {
Color.black.opacity(0.1)
}
}
.ignoresSafeArea() .ignoresSafeArea()
.interactiveDismissDisabled(indicator.interactiveDismissDisabled) .interactiveDismissDisabled(indicator.interactiveDismissDisabled)
} }
@@ -70,13 +74,16 @@ struct UserIndicatorModalView_Previews: PreviewProvider {
.previewDisplayName("Spinner") .previewDisplayName("Spinner")
UserIndicatorModalView(indicator: UserIndicator(type: .modal(progress: .published(CurrentValueSubject<Double, Never>(0.5).asCurrentValuePublisher()), UserIndicatorModalView(indicator: UserIndicator(type: .modal(progress: .published(CurrentValueSubject<Double, Never>(0.5).asCurrentValuePublisher()),
interactiveDismissDisabled: false), interactiveDismissDisabled: false,
allowsInteraction: false),
title: "Successfully logged in", title: "Successfully logged in",
iconName: "checkmark") iconName: "checkmark")
) )
.previewDisplayName("Progress Bar") .previewDisplayName("Progress Bar")
UserIndicatorModalView(indicator: UserIndicator(type: .modal(progress: .none, interactiveDismissDisabled: false), UserIndicatorModalView(indicator: UserIndicator(type: .modal(progress: .none,
interactiveDismissDisabled: false,
allowsInteraction: false),
title: "Successfully logged in", title: "Successfully logged in",
iconName: "checkmark") iconName: "checkmark")
) )
@@ -88,7 +88,7 @@ final class BugReportScreenCoordinator: CoordinatorProtocol {
private func startLoading(label: String = L10n.commonLoading, progressPublisher: CurrentValuePublisher<Double, Never>) { private func startLoading(label: String = L10n.commonLoading, progressPublisher: CurrentValuePublisher<Double, Never>) {
parameters.userIndicatorController?.submitIndicator( parameters.userIndicatorController?.submitIndicator(
UserIndicator(id: Self.loadingIndicatorIdentifier, UserIndicator(id: Self.loadingIndicatorIdentifier,
type: .modal(progress: .published(progressPublisher), interactiveDismissDisabled: false), type: .modal(progress: .published(progressPublisher), interactiveDismissDisabled: false, allowsInteraction: false),
title: label, title: label,
persistent: true) persistent: true)
) )
@@ -175,7 +175,7 @@ class CreateRoomViewModel: CreateRoomViewModelType, CreateRoomViewModelProtocol
private func showLoadingIndicator() { private func showLoadingIndicator() {
userIndicatorController?.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier, userIndicatorController?.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
type: .modal(progress: .indeterminate, interactiveDismissDisabled: true), type: .modal(progress: .indeterminate, interactiveDismissDisabled: true, allowsInteraction: false),
title: L10n.commonLoading, title: L10n.commonLoading,
persistent: true)) persistent: true))
} }
@@ -305,7 +305,7 @@ class HomeScreenViewModel: HomeScreenViewModelType, HomeScreenViewModelProtocol
state.bindings.alertInfo = AlertInfo(id: UUID(), title: L10n.errorUnknown) state.bindings.alertInfo = AlertInfo(id: UUID(), title: L10n.errorUnknown)
case .some(.success): case .some(.success):
userIndicatorController.submitIndicator(UserIndicator(id: UUID().uuidString, userIndicatorController.submitIndicator(UserIndicator(id: UUID().uuidString,
type: .modal(progress: .none, interactiveDismissDisabled: false), type: .modal(progress: .none, interactiveDismissDisabled: false, allowsInteraction: false),
title: L10n.commonCurrentUserLeftRoom, title: L10n.commonCurrentUserLeftRoom,
iconName: "checkmark")) iconName: "checkmark"))
callback?(.roomLeft(roomIdentifier: roomId)) callback?(.roomLeft(roomIdentifier: roomId))
@@ -23,6 +23,7 @@ enum MediaUploadPreviewScreenViewModelAction {
struct MediaUploadPreviewScreenViewState: BindableState { struct MediaUploadPreviewScreenViewState: BindableState {
let url: URL let url: URL
let title: String? let title: String?
var shouldDisableInteraction = false
} }
enum MediaUploadPreviewScreenViewAction { enum MediaUploadPreviewScreenViewAction {
@@ -15,6 +15,7 @@
// //
import Combine import Combine
import MatrixRustSDK
import SwiftUI import SwiftUI
typealias MediaUploadPreviewScreenViewModelType = StateStoreViewModel<MediaUploadPreviewScreenViewState, MediaUploadPreviewScreenViewAction> typealias MediaUploadPreviewScreenViewModelType = StateStoreViewModel<MediaUploadPreviewScreenViewState, MediaUploadPreviewScreenViewAction>
@@ -24,6 +25,11 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
private let roomProxy: RoomProxyProtocol private let roomProxy: RoomProxyProtocol
private let mediaUploadingPreprocessor: MediaUploadingPreprocessor private let mediaUploadingPreprocessor: MediaUploadingPreprocessor
private let url: URL private let url: URL
private var requestHandle: SendAttachmentJoinHandleProtocol? {
didSet {
state.shouldDisableInteraction = requestHandle != nil
}
}
var callback: ((MediaUploadPreviewScreenViewModelAction) -> Void)? var callback: ((MediaUploadPreviewScreenViewModelAction) -> Void)?
@@ -67,6 +73,7 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
} }
case .cancel: case .cancel:
requestHandle?.cancel()
callback?(.dismiss) callback?(.dismiss)
} }
} }
@@ -74,15 +81,20 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
// MARK: - Private // MARK: - Private
private func sendAttachment(mediaInfo: MediaInfo, progressSubject: CurrentValueSubject<Double, Never>) async -> Result<Void, RoomProxyError> { private func sendAttachment(mediaInfo: MediaInfo, progressSubject: CurrentValueSubject<Double, Never>) async -> Result<Void, RoomProxyError> {
let requestHandle: ((SendAttachmentJoinHandleProtocol) -> Void) = { [weak self] handle in
self?.requestHandle?.cancel()
self?.requestHandle = handle
}
switch mediaInfo { switch mediaInfo {
case let .image(imageURL, thumbnailURL, imageInfo): case let .image(imageURL, thumbnailURL, imageInfo):
return await roomProxy.sendImage(url: imageURL, thumbnailURL: thumbnailURL, imageInfo: imageInfo, progressSubject: progressSubject) return await roomProxy.sendImage(url: imageURL, thumbnailURL: thumbnailURL, imageInfo: imageInfo, progressSubject: progressSubject, requestHandle: requestHandle)
case let .video(videoURL, thumbnailURL, videoInfo): case let .video(videoURL, thumbnailURL, videoInfo):
return await roomProxy.sendVideo(url: videoURL, thumbnailURL: thumbnailURL, videoInfo: videoInfo, progressSubject: progressSubject) return await roomProxy.sendVideo(url: videoURL, thumbnailURL: thumbnailURL, videoInfo: videoInfo, progressSubject: progressSubject, requestHandle: requestHandle)
case let .audio(audioURL, audioInfo): case let .audio(audioURL, audioInfo):
return await roomProxy.sendAudio(url: audioURL, audioInfo: audioInfo, progressSubject: progressSubject) return await roomProxy.sendAudio(url: audioURL, audioInfo: audioInfo, progressSubject: progressSubject, requestHandle: requestHandle)
case let .file(fileURL, fileInfo): case let .file(fileURL, fileInfo):
return await roomProxy.sendFile(url: fileURL, fileInfo: fileInfo, progressSubject: progressSubject) return await roomProxy.sendFile(url: fileURL, fileInfo: fileInfo, progressSubject: progressSubject, requestHandle: requestHandle)
} }
} }
@@ -91,7 +103,7 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
private func startLoading(progressPublisher: CurrentValuePublisher<Double, Never>) { private func startLoading(progressPublisher: CurrentValuePublisher<Double, Never>) {
userIndicatorController?.submitIndicator( userIndicatorController?.submitIndicator(
UserIndicator(id: Self.loadingIndicatorIdentifier, UserIndicator(id: Self.loadingIndicatorIdentifier,
type: .modal(progress: .published(progressPublisher), interactiveDismissDisabled: false), type: .modal(progress: .published(progressPublisher), interactiveDismissDisabled: false, allowsInteraction: true),
title: L10n.commonSending, title: L10n.commonSending,
persistent: true) persistent: true)
) )
@@ -99,6 +111,7 @@ class MediaUploadPreviewScreenViewModel: MediaUploadPreviewScreenViewModelType,
private func stopLoading() { private func stopLoading() {
userIndicatorController?.retractIndicatorWithId(Self.loadingIndicatorIdentifier) userIndicatorController?.retractIndicatorWithId(Self.loadingIndicatorIdentifier)
requestHandle = nil
} }
private func showError(label: String) { private func showError(label: String) {
@@ -25,6 +25,7 @@ struct MediaUploadPreviewScreen: View {
fileURL: context.viewState.url, fileURL: context.viewState.url,
title: context.viewState.title) title: context.viewState.title)
.id(UUID()) .id(UUID())
.disabled(context.viewState.shouldDisableInteraction)
.ignoresSafeArea(edges: .bottom) .ignoresSafeArea(edges: .bottom)
.toolbar { toolbar } .toolbar { toolbar }
.interactiveDismissDisabled() .interactiveDismissDisabled()
@@ -41,6 +42,7 @@ struct MediaUploadPreviewScreen: View {
Button { context.send(viewAction: .send) } label: { Button { context.send(viewAction: .send) } label: {
Text(L10n.actionSend) Text(L10n.actionSend)
} }
.disabled(context.viewState.shouldDisableInteraction)
} }
} }
} }
@@ -78,7 +78,7 @@ class RoomDetailsEditScreenViewModel: RoomDetailsEditScreenViewModelType, RoomDe
userIndicatorController?.retractIndicatorWithId(userIndicatorID) userIndicatorController?.retractIndicatorWithId(userIndicatorID)
} }
userIndicatorController?.submitIndicator(UserIndicator(id: userIndicatorID, userIndicatorController?.submitIndicator(UserIndicator(id: userIndicatorID,
type: .modal(progress: .indeterminate, interactiveDismissDisabled: true), type: .modal(progress: .indeterminate, interactiveDismissDisabled: true, allowsInteraction: false),
title: L10n.commonLoading, title: L10n.commonLoading,
persistent: true)) persistent: true))
@@ -102,7 +102,7 @@ class RoomDetailsEditScreenViewModel: RoomDetailsEditScreenViewModelType, RoomDe
userIndicatorController?.retractIndicatorWithId(userIndicatorID) userIndicatorController?.retractIndicatorWithId(userIndicatorID)
} }
userIndicatorController?.submitIndicator(UserIndicator(id: userIndicatorID, userIndicatorController?.submitIndicator(UserIndicator(id: userIndicatorID,
type: .modal(progress: .indeterminate, interactiveDismissDisabled: true), type: .modal(progress: .indeterminate, interactiveDismissDisabled: true, allowsInteraction: false),
title: L10n.screenRoomDetailsUpdatingRoom, title: L10n.screenRoomDetailsUpdatingRoom,
persistent: true)) persistent: true))
@@ -568,7 +568,7 @@ class RoomScreenViewModel: RoomScreenViewModelType, RoomScreenViewModelProtocol
private func showLoadingIndicator(with delay: Duration) { private func showLoadingIndicator(with delay: Duration) {
userIndicatorController.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier, userIndicatorController.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
type: .modal(progress: .indeterminate, interactiveDismissDisabled: true), type: .modal(progress: .indeterminate, interactiveDismissDisabled: true, allowsInteraction: false),
title: L10n.commonLoading, title: L10n.commonLoading,
persistent: true), persistent: true),
delay: delay) delay: delay)
@@ -163,7 +163,7 @@ class StartChatScreenViewModel: StartChatScreenViewModelType, StartChatScreenVie
private func showLoadingIndicator() { private func showLoadingIndicator() {
userIndicatorController?.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier, userIndicatorController?.submitIndicator(UserIndicator(id: Self.loadingIndicatorIdentifier,
type: .modal(progress: .indeterminate, interactiveDismissDisabled: true), type: .modal(progress: .indeterminate, interactiveDismissDisabled: true, allowsInteraction: false),
title: L10n.commonLoading, title: L10n.commonLoading,
persistent: true)) persistent: true))
} }
+70 -44
View File
@@ -274,76 +274,102 @@ class RoomProxy: RoomProxyProtocol {
} }
} }
func sendImage(url: URL, thumbnailURL: URL, imageInfo: ImageInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> { func sendImage(url: URL,
thumbnailURL: URL,
imageInfo: ImageInfo,
progressSubject: CurrentValueSubject<Double, Never>?,
requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
return await Task.dispatch(on: userInitiatedDispatchQueue) { let handle = room.sendImage(url: url.path(), thumbnailUrl: thumbnailURL.path(), imageInfo: imageInfo, progressWatcher: UploadProgressListener { progress in
do { progressSubject?.send(progress)
try self.room.sendImage(url: url.path(), thumbnailUrl: thumbnailURL.path(), imageInfo: imageInfo, progressWatcher: UploadProgressListener { progress in })
progressSubject?.send(progress)
}) requestHandle(handle)
return .success(())
} catch { do {
return .failure(.failedSendingMedia) try await handle.join()
} } catch {
return .failure(.failedSendingMedia)
} }
return .success(())
} }
func sendVideo(url: URL, thumbnailURL: URL, videoInfo: VideoInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> { func sendVideo(url: URL,
thumbnailURL: URL,
videoInfo: VideoInfo,
progressSubject: CurrentValueSubject<Double, Never>?,
requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
return await Task.dispatch(on: userInitiatedDispatchQueue) { let handle = room.sendVideo(url: url.path(), thumbnailUrl: thumbnailURL.path(), videoInfo: videoInfo, progressWatcher: UploadProgressListener { progress in
do { progressSubject?.send(progress)
try self.room.sendVideo(url: url.path(), thumbnailUrl: thumbnailURL.path(), videoInfo: videoInfo, progressWatcher: UploadProgressListener { progress in })
progressSubject?.send(progress)
}) requestHandle(handle)
return .success(())
} catch { do {
return .failure(.failedSendingMedia) try await handle.join()
} } catch {
return .failure(.failedSendingMedia)
} }
return .success(())
} }
func sendAudio(url: URL, audioInfo: AudioInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> { func sendAudio(url: URL,
audioInfo: AudioInfo,
progressSubject: CurrentValueSubject<Double, Never>?,
requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
return await Task.dispatch(on: userInitiatedDispatchQueue) { let handle = room.sendAudio(url: url.path(), audioInfo: audioInfo, progressWatcher: UploadProgressListener { progress in
do { progressSubject?.send(progress)
try self.room.sendAudio(url: url.path(), audioInfo: audioInfo, progressWatcher: UploadProgressListener { progress in })
progressSubject?.send(progress)
}) requestHandle(handle)
return .success(())
} catch { do {
return .failure(.failedSendingMedia) try await handle.join()
} } catch {
return .failure(.failedSendingMedia)
} }
return .success(())
} }
func sendFile(url: URL, fileInfo: FileInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> { func sendFile(url: URL,
fileInfo: FileInfo,
progressSubject: CurrentValueSubject<Double, Never>?,
requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError> {
sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true) sendMessageBackgroundTask = backgroundTaskService.startBackgroundTask(withName: backgroundTaskName, isReusable: true)
defer { defer {
sendMessageBackgroundTask?.stop() sendMessageBackgroundTask?.stop()
} }
return await Task.dispatch(on: userInitiatedDispatchQueue) { let handle = room.sendFile(url: url.path(), fileInfo: fileInfo, progressWatcher: UploadProgressListener { progress in
do { progressSubject?.send(progress)
try self.room.sendFile(url: url.path(), fileInfo: fileInfo, progressWatcher: UploadProgressListener { progress in })
progressSubject?.send(progress)
}) requestHandle(handle)
return .success(())
} catch { do {
return .failure(.failedSendingMedia) try await handle.join()
} } catch {
return .failure(.failedSendingMedia)
} }
return .success(())
} }
func sendLocation(body: String, geoURI: GeoURI) async -> Result<Void, RoomProxyError> { func sendLocation(body: String, geoURI: GeoURI) async -> Result<Void, RoomProxyError> {
@@ -93,13 +93,27 @@ protocol RoomProxyProtocol {
func toggleReaction(_ reaction: String, to eventID: String) async -> Result<Void, RoomProxyError> func toggleReaction(_ reaction: String, to eventID: String) async -> Result<Void, RoomProxyError>
func sendImage(url: URL, thumbnailURL: URL, imageInfo: ImageInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> func sendImage(url: URL,
thumbnailURL: URL,
imageInfo: ImageInfo,
progressSubject: CurrentValueSubject<Double, Never>?,
requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError>
func sendVideo(url: URL, thumbnailURL: URL, videoInfo: VideoInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> func sendVideo(url: URL,
thumbnailURL: URL,
videoInfo: VideoInfo,
progressSubject: CurrentValueSubject<Double, Never>?,
requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError>
func sendAudio(url: URL, audioInfo: AudioInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> func sendAudio(url: URL,
audioInfo: AudioInfo,
progressSubject: CurrentValueSubject<Double, Never>?,
requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError>
func sendFile(url: URL, fileInfo: FileInfo, progressSubject: CurrentValueSubject<Double, Never>?) async -> Result<Void, RoomProxyError> func sendFile(url: URL,
fileInfo: FileInfo,
progressSubject: CurrentValueSubject<Double, Never>?,
requestHandle: (SendAttachmentJoinHandleProtocol) -> Void) async -> Result<Void, RoomProxyError>
func sendLocation(body: String, geoURI: GeoURI) async -> Result<Void, RoomProxyError> func sendLocation(body: String, geoURI: GeoURI) async -> Result<Void, RoomProxyError>
+1 -1
View File
@@ -44,7 +44,7 @@ include:
packages: packages:
MatrixRustSDK: MatrixRustSDK:
url: https://github.com/matrix-org/matrix-rust-components-swift url: https://github.com/matrix-org/matrix-rust-components-swift
exactVersion: 1.0.89-alpha exactVersion: 1.0.91-alpha
# path: ../matrix-rust-sdk # path: ../matrix-rust-sdk
DesignKit: DesignKit:
path: DesignKit path: DesignKit