Fixes #3137 - Delay starting ElementCall until a sync response comes in (or a 5 second timeout)
- this will ensure that the room state is up to date before sending any call related events
This commit is contained in:
committed by
Stefan Ceriu
parent
33b78e1b11
commit
cdc1c44464
@@ -31,6 +31,8 @@ class CallScreenViewModel: CallScreenViewModelType, CallScreenViewModelProtocol
|
||||
actionsSubject.eraseToAnyPublisher()
|
||||
}
|
||||
|
||||
private var syncUpdateCancellable: AnyCancellable?
|
||||
|
||||
/// Designated initialiser
|
||||
/// - Parameters:
|
||||
/// - elementCallService: service responsible for setting up CallKit
|
||||
@@ -113,31 +115,42 @@ class CallScreenViewModel: CallScreenViewModelType, CallScreenViewModelProtocol
|
||||
}
|
||||
.store(in: &cancellables)
|
||||
|
||||
Task {
|
||||
let baseURL = if let elementCallBaseURLOverride {
|
||||
elementCallBaseURLOverride
|
||||
} else if case .success(let wellKnown) = await clientProxy.getElementWellKnown(), let wellKnownCall = wellKnown?.call {
|
||||
wellKnownCall.widgetURL
|
||||
} else {
|
||||
elementCallBaseURL
|
||||
}
|
||||
|
||||
switch await widgetDriver.start(baseURL: baseURL, clientID: clientID, colorScheme: colorScheme) {
|
||||
case .success(let url):
|
||||
state.url = url
|
||||
case .failure(let error):
|
||||
MXLog.error("Failed starting ElementCall Widget Driver with error: \(error)")
|
||||
state.bindings.alertInfo = .init(id: UUID(), title: L10n.errorUnknown, primaryButton: .init(title: L10n.actionOk, action: { [weak self] in
|
||||
self?.actionsSubject.send(.dismiss)
|
||||
}))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
await elementCallService.setupCallSession(roomID: roomProxy.id, roomDisplayName: roomProxy.roomTitle)
|
||||
|
||||
let _ = await roomProxy.sendCallNotificationIfNeeeded()
|
||||
}
|
||||
// Wait for room states to be up to date before starting the call and notifying others
|
||||
syncUpdateCancellable = clientProxy.actionsPublisher
|
||||
.filter(\.isSyncUpdate)
|
||||
.timeout(.seconds(5), scheduler: DispatchQueue.main)
|
||||
.first() // Timeout will make the publisher complete, use first to handle both branches in the same place
|
||||
.sink(receiveCompletion: { [weak self] _ in
|
||||
Task { [weak self] in
|
||||
guard let self else { return }
|
||||
|
||||
let baseURL = if let elementCallBaseURLOverride {
|
||||
elementCallBaseURLOverride
|
||||
} else if case .success(let wellKnown) = await clientProxy.getElementWellKnown(), let wellKnownCall = wellKnown?.call {
|
||||
wellKnownCall.widgetURL
|
||||
} else {
|
||||
elementCallBaseURL
|
||||
}
|
||||
|
||||
switch await widgetDriver.start(baseURL: baseURL, clientID: clientID, colorScheme: colorScheme) {
|
||||
case .success(let url):
|
||||
state.url = url
|
||||
case .failure(let error):
|
||||
MXLog.error("Failed starting ElementCall Widget Driver with error: \(error)")
|
||||
state.bindings.alertInfo = .init(id: UUID(), title: L10n.errorUnknown, primaryButton: .init(title: L10n.actionOk, action: { [weak self] in
|
||||
self?.actionsSubject.send(.dismiss)
|
||||
}))
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
await elementCallService.setupCallSession(roomID: roomProxy.id, roomDisplayName: roomProxy.roomTitle)
|
||||
|
||||
_ = await roomProxy.sendCallNotificationIfNeeeded()
|
||||
|
||||
syncUpdateCancellable = nil
|
||||
}
|
||||
}, receiveValue: { _ in })
|
||||
}
|
||||
|
||||
override func process(viewAction: CallScreenViewAction) {
|
||||
|
||||
@@ -22,12 +22,16 @@ struct CallScreen: View {
|
||||
@ObservedObject var context: CallScreenViewModel.Context
|
||||
|
||||
var body: some View {
|
||||
WebView(url: context.viewState.url, viewModelContext: context)
|
||||
// This URL is stable, forces view reloads if this representable is ever reused for another url
|
||||
.id(context.viewState.url)
|
||||
.ignoresSafeArea(edges: .bottom)
|
||||
.presentationDragIndicator(.visible)
|
||||
.alert(item: $context.alertInfo)
|
||||
if context.viewState.url == nil {
|
||||
ProgressView()
|
||||
} else {
|
||||
WebView(url: context.viewState.url, viewModelContext: context)
|
||||
// This URL is stable, forces view reloads if this representable is ever reused for another url
|
||||
.id(context.viewState.url)
|
||||
.ignoresSafeArea(edges: .bottom)
|
||||
.presentationDragIndicator(.visible)
|
||||
.alert(item: $context.alertInfo)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user