add detailed call connection info

pull/1061/head
Ryan ZHAO 3 months ago
parent 753b93bb9e
commit 4fc848ebdc

@ -87,6 +87,7 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
didSet {
stateDidChange?()
hasConnectedDidChange?()
updateCallDetailedStatus?("Call Connected")
}
}
@ -94,6 +95,7 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
didSet {
stateDidChange?()
hasEndedDidChange?()
updateCallDetailedStatus?("")
}
}
@ -113,6 +115,7 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
var remoteVideoStateDidChange: ((Bool) -> Void)?
var hasStartedReconnecting: (() -> Void)?
var hasReconnected: (() -> Void)?
var updateCallDetailedStatus: ((String) -> Void)?
// MARK: - Derived Properties
@ -249,6 +252,8 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
self.callInteractionId = interaction?.id
self.updateCallDetailedStatus?("Creating Call")
try? webRTCSession
.sendPreOffer(
db,
@ -259,8 +264,9 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
.retry(5)
// Start the timeout timer for the call
.handleEvents(receiveOutput: { [weak self] _ in self?.setupTimeoutTimer() })
.flatMap { _ in
webRTCSession
.flatMap { [weak self] _ in
self?.updateCallDetailedStatus?("Sending Call Offer")
return webRTCSession
.sendOffer(to: thread)
.retry(5)
}
@ -269,6 +275,7 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
switch result {
case .finished:
SNLog("[Calls] Offer message sent")
self?.updateCallDetailedStatus?("Sending Connection Candidates")
case .failure(let error):
SNLog("[Calls] Error initializing call after 5 retries: \(error), ending call...")
self?.handleCallInitializationFailed()
@ -284,6 +291,7 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
if let sdp = remoteSDP {
SNLog("[Calls] Got remote sdp already")
self.updateCallDetailedStatus?("Answering Call")
webRTCSession.handleRemoteSDP(sdp, from: sessionId) // This sends an answer message internally
}
}
@ -422,6 +430,18 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
isRemoteVideoEnabled = isEnabled
}
public func iceCandidateDidSend() {
DispatchQueue.main.async {
self.updateCallDetailedStatus?("Awaiting Recipient Answer...")
}
}
public func iceCandidateDidReceive() {
DispatchQueue.main.async {
self.updateCallDetailedStatus?("Handling Connection Candidates")
}
}
public func didReceiveHangUpSignal() {
self.hasEnded = true
DispatchQueue.main.async {

@ -315,7 +315,6 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
result.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
result.themeTextColor = .textPrimary
result.textAlignment = .center
result.isHidden = call.hasConnected
if call.hasStartedConnecting { result.text = "callsConnecting".localized() }
@ -331,6 +330,15 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
return result
}()
private lazy var callInfoLabelStackView: UIStackView = {
let result: UIStackView = UIStackView(arrangedSubviews: [callInfoLabel, callDetailedInfoLabel])
result.axis = .vertical
result.spacing = Values.mediumSpacing
result.isHidden = call.hasConnected
return result
}()
private lazy var callDurationLabel: UILabel = {
let result = UILabel()
result.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
@ -359,11 +367,11 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
remoteVideoView.alpha = isEnabled ? 1 : 0
}
if self.callInfoLabel.alpha < 0.5 {
if self.callInfoLabelStackView.alpha < 0.5 {
UIView.animate(withDuration: 0.25) {
self.operationPanel.alpha = 1
self.responsePanel.alpha = 1
self.callInfoLabel.alpha = 1
self.callInfoLabelStackView.alpha = 1
}
}
}
@ -396,7 +404,7 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
self?.durationTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
self?.updateDuration()
}
self?.callInfoLabel.isHidden = true
self?.callInfoLabelStackView.isHidden = true
self?.callDurationLabel.isHidden = false
}
}
@ -411,7 +419,7 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
self.call.hasStartedReconnecting = { [weak self] in
DispatchQueue.main.async {
self?.callInfoLabel.isHidden = false
self?.callInfoLabelStackView.isHidden = false
self?.callDurationLabel.isHidden = true
self?.callInfoLabel.text = "callsReconnecting".localized()
}
@ -419,10 +427,16 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
self.call.hasReconnected = { [weak self] in
DispatchQueue.main.async {
self?.callInfoLabel.isHidden = true
self?.callInfoLabelStackView.isHidden = true
self?.callDurationLabel.isHidden = false
}
}
self.call.updateCallDetailedStatus = { [weak self] status in
DispatchQueue.main.async {
self?.callDetailedInfoLabel.text = status
}
}
}
required init(coder: NSCoder) { preconditionFailure("Use init(for:) instead.") }
@ -519,10 +533,10 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
callInfoLabelContainer.pin(.top, to: .bottom, of: profilePictureView)
callInfoLabelContainer.pin(.bottom, to: .bottom, of: profilePictureContainer)
callInfoLabelContainer.pin([ UIView.HorizontalEdge.left, UIView.HorizontalEdge.right ], to: view)
callInfoLabelContainer.addSubview(callInfoLabel)
callInfoLabelContainer.addSubview(callInfoLabelStackView)
callInfoLabelContainer.addSubview(callDurationLabel)
callInfoLabel.translatesAutoresizingMaskIntoConstraints = false
callInfoLabel.center(in: callInfoLabelContainer)
callInfoLabelStackView.translatesAutoresizingMaskIntoConstraints = false
callInfoLabelStackView.center(in: callInfoLabelContainer)
callDurationLabel.translatesAutoresizingMaskIntoConstraints = false
callDurationLabel.center(in: callInfoLabelContainer)
}
@ -596,7 +610,7 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
func handleEndCallMessage() {
SNLog("[Calls] Ending call.")
self.callInfoLabel.isHidden = false
self.callInfoLabelStackView.isHidden = false
self.callDurationLabel.isHidden = true
self.callInfoLabel.text = "callsEnded".localized()
@ -605,7 +619,7 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
remoteVideoView.alpha = 0
self.operationPanel.alpha = 1
self.responsePanel.alpha = 1
self.callInfoLabel.alpha = 1
self.callInfoLabelStackView.alpha = 1
}
Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { [weak self] _ in

@ -9,6 +9,7 @@ extension WebRTCSession {
public func handleICECandidates(_ candidate: [RTCIceCandidate]) {
SNLog("[Calls] Received ICE candidate message.")
self.delegate?.iceCandidateDidReceive()
candidate.forEach { peerConnection?.add($0, completionHandler: { _ in }) }
}

@ -12,6 +12,8 @@ public protocol WebRTCSessionDelegate: AnyObject {
func webRTCIsConnected()
func isRemoteVideoDidChange(isEnabled: Bool)
func iceCandidateDidSend()
func iceCandidateDidReceive()
func dataChannelDidOpen()
func didReceiveHangUpSignal()
func reconnectIfNeeded()
@ -339,9 +341,21 @@ public final class WebRTCSession : NSObject, RTCPeerConnectionDelegate {
}
.subscribe(on: DispatchQueue.global(qos: .userInitiated))
.flatMap { [dependencies = self.dependencies] sendData in
MessageSender.sendImmediate(data: sendData, using: dependencies)
MessageSender
.sendImmediate(data: sendData, using: dependencies)
.retry(5)
}
.sinkUntilComplete()
.sinkUntilComplete(
receiveCompletion: { [weak self] result in
switch result {
case .finished:
SNLog("[Calls] ICE candidates sent")
self?.delegate?.iceCandidateDidSend()
case .failure(let error):
SNLog("[Calls] Error sending ICE candidates due to error: \(error)")
}
}
)
}
public func endCall(

Loading…
Cancel
Save