0.10.6
This commit is contained in:
commit
92660a4ba0
228 files changed
+24496
No files matched your search
@@ -0,0 +1,114 @@
|
||||
import Foundation
|
||||
|
||||
enum CallMedia: String, CaseIterable, Hashable, Sendable {
|
||||
case audio
|
||||
case video
|
||||
}
|
||||
|
||||
enum CallDirection: String, Equatable, Sendable {
|
||||
case incoming
|
||||
case outgoing
|
||||
}
|
||||
|
||||
enum CallPhase: Equatable, Sendable {
|
||||
case ringing
|
||||
case connecting
|
||||
case connected
|
||||
}
|
||||
|
||||
/// Stable value stored with a local call-history message.
|
||||
enum CallHistoryOutcome: String, Codable, Hashable, Sendable {
|
||||
case completed
|
||||
case declined
|
||||
case missed
|
||||
case cancelled
|
||||
case unanswered
|
||||
case failed
|
||||
case answeredElsewhere
|
||||
}
|
||||
|
||||
struct CallHistoryMetadata: Codable, Hashable, Sendable {
|
||||
let isVideo: Bool
|
||||
let outcome: CallHistoryOutcome
|
||||
}
|
||||
|
||||
/// Internal reason used to turn every call-ending path into one history result.
|
||||
enum CallTerminationCause: Equatable, Sendable {
|
||||
case localEnded
|
||||
case localRejected
|
||||
case remoteEnded
|
||||
case remoteRejected
|
||||
case remoteCancelled
|
||||
case timedOut
|
||||
case failed
|
||||
case connectionDetached
|
||||
case answeredElsewhere
|
||||
}
|
||||
|
||||
struct CallHistoryEntry: Equatable, Sendable {
|
||||
let id: String
|
||||
let peerJID: String
|
||||
let direction: CallDirection
|
||||
let isVideo: Bool
|
||||
let startedAt: Date
|
||||
let endedAt: Date
|
||||
let duration: TimeInterval?
|
||||
let outcome: CallHistoryOutcome
|
||||
}
|
||||
|
||||
/// Pure classification kept outside WebRTC so every termination scenario can
|
||||
/// be tested without constructing a live peer connection.
|
||||
enum CallHistoryPolicy {
|
||||
static func outcome(
|
||||
direction: CallDirection,
|
||||
phase: CallPhase,
|
||||
connectedAt: Date?,
|
||||
cause: CallTerminationCause
|
||||
) -> CallHistoryOutcome {
|
||||
// Once media connected, a later hang-up or transport loss still belongs
|
||||
// to the successful-call history and keeps its measured duration.
|
||||
if connectedAt != nil || phase == .connected {
|
||||
return .completed
|
||||
}
|
||||
|
||||
switch cause {
|
||||
case .localRejected, .remoteRejected:
|
||||
return .declined
|
||||
case .localEnded:
|
||||
return .cancelled
|
||||
case .remoteCancelled, .remoteEnded:
|
||||
guard phase == .ringing else { return .failed }
|
||||
return direction == .incoming ? .missed : .declined
|
||||
case .timedOut:
|
||||
guard phase == .ringing else { return .failed }
|
||||
return direction == .incoming ? .missed : .unanswered
|
||||
case .answeredElsewhere:
|
||||
return .answeredElsewhere
|
||||
case .failed, .connectionDetached:
|
||||
return .failed
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// Value-type projection of the live WebRTC/Jingle session used by SwiftUI.
|
||||
struct CallSnapshot: Identifiable, Equatable, Sendable {
|
||||
let id: UUID
|
||||
let peerJID: String
|
||||
let direction: CallDirection
|
||||
let media: Set<CallMedia>
|
||||
let phase: CallPhase
|
||||
let connectedAt: Date?
|
||||
let isMuted: Bool
|
||||
let isCameraEnabled: Bool
|
||||
let isSpeakerEnabled: Bool
|
||||
let hasLocalVideo: Bool
|
||||
let hasRemoteVideo: Bool
|
||||
|
||||
var isVideoCall: Bool {
|
||||
media.contains(.video)
|
||||
}
|
||||
|
||||
var isIncomingRinging: Bool {
|
||||
direction == .incoming && phase == .ringing
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user