Skip to content

Commit

Permalink
Merge pull request #359 from session-foundation/dev
Browse files Browse the repository at this point in the history
Release 2.8.7
  • Loading branch information
RyanRory authored Jan 23, 2025
2 parents b75c70c + 7d399db commit 55779b0
Show file tree
Hide file tree
Showing 23 changed files with 284 additions and 81 deletions.
8 changes: 8 additions & 0 deletions Session.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,7 @@
9473386E2BDF5F3E00B9E169 /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 9473386D2BDF5F3E00B9E169 /* InfoPlist.xcstrings */; };
947AD6902C8968FF000B2730 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 947AD68F2C8968FF000B2730 /* Constants.swift */; };
94B3DC172AF8592200C88531 /* QuoteView_SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94B3DC162AF8592200C88531 /* QuoteView_SwiftUI.swift */; };
94C58AC92D2E037200609195 /* Permissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C58AC82D2E036E00609195 /* Permissions.swift */; };
94C5DCB02BE88170003AA8C5 /* BezierPathView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C5DCAF2BE88170003AA8C5 /* BezierPathView.swift */; };
94E9BC0D2C7BFBDA006984EA /* Localization+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94E9BC0C2C7BFBDA006984EA /* Localization+Style.swift */; };
A11CD70D17FA230600A2D1B1 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A11CD70C17FA230600A2D1B1 /* QuartzCore.framework */; };
Expand Down Expand Up @@ -1398,6 +1399,7 @@
9473386D2BDF5F3E00B9E169 /* InfoPlist.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = InfoPlist.xcstrings; sourceTree = "<group>"; };
947AD68F2C8968FF000B2730 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
94B3DC162AF8592200C88531 /* QuoteView_SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuoteView_SwiftUI.swift; sourceTree = "<group>"; };
94C58AC82D2E036E00609195 /* Permissions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Permissions.swift; sourceTree = "<group>"; };
94C5DCAF2BE88170003AA8C5 /* BezierPathView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BezierPathView.swift; sourceTree = "<group>"; };
94E9BC0C2C7BFBDA006984EA /* Localization+Style.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Localization+Style.swift"; sourceTree = "<group>"; };
A11CD70C17FA230600A2D1B1 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -3625,6 +3627,7 @@
FD09796527F6B0A800936362 /* Utilities */ = {
isa = PBXGroup;
children = (
94C58AC82D2E036E00609195 /* Permissions.swift */,
FD6A39422C2AD81600762359 /* BackgroundTaskManager.swift */,
FDFBB74A2A1EFF4900CA7350 /* Bencode.swift */,
FD6A39162C2A99A000762359 /* BencodeDecoder.swift */,
Expand Down Expand Up @@ -5824,6 +5827,7 @@
C3C2AC2E2553CBEB00C340D1 /* String+Trimming.swift in Sources */,
FD17D7C727F5207C00122BE0 /* DatabaseMigrator+Utilities.swift in Sources */,
FD848B9328420164000E298B /* UnicodeScalar+Utilities.swift in Sources */,
94C58AC92D2E037200609195 /* Permissions.swift in Sources */,
FD09796B27F6C67500936362 /* Failable.swift in Sources */,
FD7115FA28C8153400B47552 /* UIBarButtonItem+Combine.swift in Sources */,
FD705A92278D051200F16121 /* ReusableView.swift in Sources */,
Expand Down Expand Up @@ -7825,6 +7829,7 @@
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 528;
DEVELOPMENT_TEAM = SUQ8J2PCT7;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
Expand Down Expand Up @@ -7862,6 +7867,7 @@
"$(SRCROOT)",
);
LLVM_LTO = NO;
MARKETING_VERSION = 2.8.7;
OTHER_LDFLAGS = "$(inherited)";
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger";
Expand Down Expand Up @@ -7894,6 +7900,7 @@
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
CURRENT_PROJECT_VERSION = 528;
DEVELOPMENT_TEAM = SUQ8J2PCT7;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
Expand Down Expand Up @@ -7931,6 +7938,7 @@
"$(SRCROOT)",
);
LLVM_LTO = NO;
MARKETING_VERSION = 2.8.7;
OTHER_LDFLAGS = "$(inherited)";
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger";
PRODUCT_NAME = Session;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"originHash" : "c57241b796915b0642f9c260463b2d6fd7d5198beafde785c590f3a7d80d31f5",
"originHash" : "4c95b434de06c87c75c3ef96fa055ec67e885a4a4ad78caafd7925b131995b07",
"pins" : [
{
"identity" : "cocoalumberjack",
Expand Down
44 changes: 42 additions & 2 deletions Session/Calls/Call Management/SessionCall.swift
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,15 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
didSet {
stateDidChange?()
hasConnectedDidChange?()
updateCallDetailedStatus?("Call Connected")
}
}

var endDate: Date? {
didSet {
stateDidChange?()
hasEndedDidChange?()
updateCallDetailedStatus?("")
}
}

Expand All @@ -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

Expand Down Expand Up @@ -249,17 +252,36 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {

self.callInteractionId = interaction?.id

self.updateCallDetailedStatus?("Creating Call")

try? webRTCSession
.sendPreOffer(
db,
message: message,
interactionId: interaction?.id,
in: thread
)
.retry(5)
// Start the timeout timer for the call
.handleEvents(receiveOutput: { [weak self] _ in self?.setupTimeoutTimer() })
.flatMap { _ in webRTCSession.sendOffer(to: thread) }
.sinkUntilComplete()
.flatMap { [weak self] _ in
self?.updateCallDetailedStatus?("Sending Call Offer")
return webRTCSession
.sendOffer(to: thread)
.retry(5)
}
.sinkUntilComplete(
receiveCompletion: { [weak self] result in
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()
}
}
)
}

func answerSessionCall() {
Expand All @@ -269,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
}
}
Expand All @@ -292,6 +315,11 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
hasEnded = true
}

func handleCallInitializationFailed() {
self.endSessionCall()
Singleton.callManager.reportCurrentCallEnded(reason: nil)
}

// MARK: - Call Message Handling

public func updateCallMessage(mode: EndCallMode, using dependencies: Dependencies) {
Expand Down Expand Up @@ -402,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 {
Expand Down
4 changes: 2 additions & 2 deletions Session/Calls/Call Management/SessionCallManager+Action.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ extension SessionCallManager {
let callVC = CallVC(for: call)
if let conversationVC = presentingVC as? ConversationVC {
callVC.conversationVC = conversationVC
conversationVC.inputAccessoryView?.isHidden = true
conversationVC.inputAccessoryView?.alpha = 0
conversationVC.resignFirstResponder()
conversationVC.hideInputAccessoryView()
}

presentingVC.present(callVC, animated: true) {
Expand Down
1 change: 1 addition & 0 deletions Session/Calls/Call Management/SessionCallManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,7 @@ public final class SessionCallManager: NSObject, CallManagerProtocol {
{
let callVC = CallVC(for: call)
callVC.conversationVC = conversationVC
conversationVC.resignFirstResponder()
conversationVC.hideInputAccessoryView()
presentingVC.present(callVC, animated: true, completion: nil)
}
Expand Down
45 changes: 34 additions & 11 deletions Session/Calls/CallVC.swift
Original file line number Diff line number Diff line change
Expand Up @@ -315,13 +315,30 @@ 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() }

return result
}()

private lazy var callDetailedInfoLabel: UILabel = {
let result: UILabel = UILabel()
result.font = .boldSystemFont(ofSize: Values.smallFontSize)
result.themeTextColor = .textPrimary
result.textAlignment = .center

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)
Expand Down Expand Up @@ -350,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
}
}
}
Expand Down Expand Up @@ -387,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
}
}
Expand All @@ -402,18 +419,24 @@ 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()
}
}

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.") }
Expand Down Expand Up @@ -510,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)
}
Expand Down Expand Up @@ -587,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()

Expand All @@ -596,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
Expand Down
4 changes: 2 additions & 2 deletions Session/Calls/Views & Modals/IncomingCallBanner.swift
Original file line number Diff line number Diff line change
Expand Up @@ -204,8 +204,8 @@ final class IncomingCallBanner: UIView, UIGestureRecognizerDelegate {
let callVC = CallVC(for: self.call)
if let conversationVC = (presentingVC as? TopBannerController)?.wrappedViewController() as? ConversationVC {
callVC.conversationVC = conversationVC
conversationVC.inputAccessoryView?.isHidden = true
conversationVC.inputAccessoryView?.alpha = 0
conversationVC.resignFirstResponder()
conversationVC.hideInputAccessoryView()
}

presentingVC.present(callVC, animated: true) { [weak self] in
Expand Down
5 changes: 4 additions & 1 deletion Session/Calls/WebRTC/WebRTCSession+MessageHandling.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 }) }
}

Expand All @@ -22,7 +23,9 @@ extension WebRTCSession {
else {
guard sdp.type == .offer else { return }

self?.sendAnswer(to: sessionId).sinkUntilComplete()
self?.sendAnswer(to: sessionId)
.retry(5)
.sinkUntilComplete()
}
})
}
Expand Down
19 changes: 17 additions & 2 deletions Session/Calls/WebRTC/WebRTCSession.swift
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,8 @@ public protocol WebRTCSessionDelegate: AnyObject {

func webRTCIsConnected()
func isRemoteVideoDidChange(isEnabled: Bool)
func iceCandidateDidSend()
func iceCandidateDidReceive()
func dataChannelDidOpen()
func didReceiveHangUpSignal()
func reconnectIfNeeded()
Expand Down Expand Up @@ -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(
Expand Down Expand Up @@ -375,6 +389,7 @@ public final class WebRTCSession : NSObject, RTCPeerConnectionDelegate {
MessageSender
.sendImmediate(data: preparedSendData, using: dependencies)
.subscribe(on: DispatchQueue.global(qos: .userInitiated))
.retry(5)
.sinkUntilComplete()
}

Expand Down
Loading

0 comments on commit 55779b0

Please sign in to comment.