Skip to content

Commit 55779b0

Browse files
authored
Merge pull request #359 from session-foundation/dev
Release 2.8.7
2 parents b75c70c + 7d399db commit 55779b0

File tree

23 files changed

+284
-81
lines changed

23 files changed

+284
-81
lines changed

Session.xcodeproj/project.pbxproj

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -192,6 +192,7 @@
192192
9473386E2BDF5F3E00B9E169 /* InfoPlist.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 9473386D2BDF5F3E00B9E169 /* InfoPlist.xcstrings */; };
193193
947AD6902C8968FF000B2730 /* Constants.swift in Sources */ = {isa = PBXBuildFile; fileRef = 947AD68F2C8968FF000B2730 /* Constants.swift */; };
194194
94B3DC172AF8592200C88531 /* QuoteView_SwiftUI.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94B3DC162AF8592200C88531 /* QuoteView_SwiftUI.swift */; };
195+
94C58AC92D2E037200609195 /* Permissions.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C58AC82D2E036E00609195 /* Permissions.swift */; };
195196
94C5DCB02BE88170003AA8C5 /* BezierPathView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94C5DCAF2BE88170003AA8C5 /* BezierPathView.swift */; };
196197
94E9BC0D2C7BFBDA006984EA /* Localization+Style.swift in Sources */ = {isa = PBXBuildFile; fileRef = 94E9BC0C2C7BFBDA006984EA /* Localization+Style.swift */; };
197198
A11CD70D17FA230600A2D1B1 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = A11CD70C17FA230600A2D1B1 /* QuartzCore.framework */; };
@@ -1398,6 +1399,7 @@
13981399
9473386D2BDF5F3E00B9E169 /* InfoPlist.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = InfoPlist.xcstrings; sourceTree = "<group>"; };
13991400
947AD68F2C8968FF000B2730 /* Constants.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Constants.swift; sourceTree = "<group>"; };
14001401
94B3DC162AF8592200C88531 /* QuoteView_SwiftUI.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QuoteView_SwiftUI.swift; sourceTree = "<group>"; };
1402+
94C58AC82D2E036E00609195 /* Permissions.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Permissions.swift; sourceTree = "<group>"; };
14011403
94C5DCAF2BE88170003AA8C5 /* BezierPathView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = BezierPathView.swift; sourceTree = "<group>"; };
14021404
94E9BC0C2C7BFBDA006984EA /* Localization+Style.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Localization+Style.swift"; sourceTree = "<group>"; };
14031405
A11CD70C17FA230600A2D1B1 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; };
@@ -3625,6 +3627,7 @@
36253627
FD09796527F6B0A800936362 /* Utilities */ = {
36263628
isa = PBXGroup;
36273629
children = (
3630+
94C58AC82D2E036E00609195 /* Permissions.swift */,
36283631
FD6A39422C2AD81600762359 /* BackgroundTaskManager.swift */,
36293632
FDFBB74A2A1EFF4900CA7350 /* Bencode.swift */,
36303633
FD6A39162C2A99A000762359 /* BencodeDecoder.swift */,
@@ -5824,6 +5827,7 @@
58245827
C3C2AC2E2553CBEB00C340D1 /* String+Trimming.swift in Sources */,
58255828
FD17D7C727F5207C00122BE0 /* DatabaseMigrator+Utilities.swift in Sources */,
58265829
FD848B9328420164000E298B /* UnicodeScalar+Utilities.swift in Sources */,
5830+
94C58AC92D2E037200609195 /* Permissions.swift in Sources */,
58275831
FD09796B27F6C67500936362 /* Failable.swift in Sources */,
58285832
FD7115FA28C8153400B47552 /* UIBarButtonItem+Combine.swift in Sources */,
58295833
FD705A92278D051200F16121 /* ReusableView.swift in Sources */,
@@ -7825,6 +7829,7 @@
78257829
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
78267830
CODE_SIGN_IDENTITY = "iPhone Developer";
78277831
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
7832+
CURRENT_PROJECT_VERSION = 528;
78287833
DEVELOPMENT_TEAM = SUQ8J2PCT7;
78297834
FRAMEWORK_SEARCH_PATHS = (
78307835
"$(inherited)",
@@ -7862,6 +7867,7 @@
78627867
"$(SRCROOT)",
78637868
);
78647869
LLVM_LTO = NO;
7870+
MARKETING_VERSION = 2.8.7;
78657871
OTHER_LDFLAGS = "$(inherited)";
78667872
OTHER_SWIFT_FLAGS = "$(inherited) \"-D\" \"COCOAPODS\" \"-DDEBUG\"";
78677873
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger";
@@ -7894,6 +7900,7 @@
78947900
CODE_SIGN_ENTITLEMENTS = Session/Meta/Signal.entitlements;
78957901
CODE_SIGN_IDENTITY = "iPhone Developer";
78967902
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
7903+
CURRENT_PROJECT_VERSION = 528;
78977904
DEVELOPMENT_TEAM = SUQ8J2PCT7;
78987905
FRAMEWORK_SEARCH_PATHS = (
78997906
"$(inherited)",
@@ -7931,6 +7938,7 @@
79317938
"$(SRCROOT)",
79327939
);
79337940
LLVM_LTO = NO;
7941+
MARKETING_VERSION = 2.8.7;
79347942
OTHER_LDFLAGS = "$(inherited)";
79357943
PRODUCT_BUNDLE_IDENTIFIER = "com.loki-project.loki-messenger";
79367944
PRODUCT_NAME = Session;

Session.xcodeproj/project.xcworkspace/xcshareddata/swiftpm/Package.resolved

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Session/Calls/Call Management/SessionCall.swift

Lines changed: 42 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,13 +87,15 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
8787
didSet {
8888
stateDidChange?()
8989
hasConnectedDidChange?()
90+
updateCallDetailedStatus?("Call Connected")
9091
}
9192
}
9293

9394
var endDate: Date? {
9495
didSet {
9596
stateDidChange?()
9697
hasEndedDidChange?()
98+
updateCallDetailedStatus?("")
9799
}
98100
}
99101

@@ -113,6 +115,7 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
113115
var remoteVideoStateDidChange: ((Bool) -> Void)?
114116
var hasStartedReconnecting: (() -> Void)?
115117
var hasReconnected: (() -> Void)?
118+
var updateCallDetailedStatus: ((String) -> Void)?
116119

117120
// MARK: - Derived Properties
118121

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

250253
self.callInteractionId = interaction?.id
251254

255+
self.updateCallDetailedStatus?("Creating Call")
256+
252257
try? webRTCSession
253258
.sendPreOffer(
254259
db,
255260
message: message,
256261
interactionId: interaction?.id,
257262
in: thread
258263
)
264+
.retry(5)
259265
// Start the timeout timer for the call
260266
.handleEvents(receiveOutput: { [weak self] _ in self?.setupTimeoutTimer() })
261-
.flatMap { _ in webRTCSession.sendOffer(to: thread) }
262-
.sinkUntilComplete()
267+
.flatMap { [weak self] _ in
268+
self?.updateCallDetailedStatus?("Sending Call Offer")
269+
return webRTCSession
270+
.sendOffer(to: thread)
271+
.retry(5)
272+
}
273+
.sinkUntilComplete(
274+
receiveCompletion: { [weak self] result in
275+
switch result {
276+
case .finished:
277+
SNLog("[Calls] Offer message sent")
278+
self?.updateCallDetailedStatus?("Sending Connection Candidates")
279+
case .failure(let error):
280+
SNLog("[Calls] Error initializing call after 5 retries: \(error), ending call...")
281+
self?.handleCallInitializationFailed()
282+
}
283+
}
284+
)
263285
}
264286

265287
func answerSessionCall() {
@@ -269,6 +291,7 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
269291

270292
if let sdp = remoteSDP {
271293
SNLog("[Calls] Got remote sdp already")
294+
self.updateCallDetailedStatus?("Answering Call")
272295
webRTCSession.handleRemoteSDP(sdp, from: sessionId) // This sends an answer message internally
273296
}
274297
}
@@ -292,6 +315,11 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
292315
hasEnded = true
293316
}
294317

318+
func handleCallInitializationFailed() {
319+
self.endSessionCall()
320+
Singleton.callManager.reportCurrentCallEnded(reason: nil)
321+
}
322+
295323
// MARK: - Call Message Handling
296324

297325
public func updateCallMessage(mode: EndCallMode, using dependencies: Dependencies) {
@@ -402,6 +430,18 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate {
402430
isRemoteVideoEnabled = isEnabled
403431
}
404432

433+
public func iceCandidateDidSend() {
434+
DispatchQueue.main.async {
435+
self.updateCallDetailedStatus?("Awaiting Recipient Answer...")
436+
}
437+
}
438+
439+
public func iceCandidateDidReceive() {
440+
DispatchQueue.main.async {
441+
self.updateCallDetailedStatus?("Handling Connection Candidates")
442+
}
443+
}
444+
405445
public func didReceiveHangUpSignal() {
406446
self.hasEnded = true
407447
DispatchQueue.main.async {

Session/Calls/Call Management/SessionCallManager+Action.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -28,8 +28,8 @@ extension SessionCallManager {
2828
let callVC = CallVC(for: call)
2929
if let conversationVC = presentingVC as? ConversationVC {
3030
callVC.conversationVC = conversationVC
31-
conversationVC.inputAccessoryView?.isHidden = true
32-
conversationVC.inputAccessoryView?.alpha = 0
31+
conversationVC.resignFirstResponder()
32+
conversationVC.hideInputAccessoryView()
3333
}
3434

3535
presentingVC.present(callVC, animated: true) {

Session/Calls/Call Management/SessionCallManager.swift

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -246,6 +246,7 @@ public final class SessionCallManager: NSObject, CallManagerProtocol {
246246
{
247247
let callVC = CallVC(for: call)
248248
callVC.conversationVC = conversationVC
249+
conversationVC.resignFirstResponder()
249250
conversationVC.hideInputAccessoryView()
250251
presentingVC.present(callVC, animated: true, completion: nil)
251252
}

Session/Calls/CallVC.swift

Lines changed: 34 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -315,13 +315,30 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
315315
result.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
316316
result.themeTextColor = .textPrimary
317317
result.textAlignment = .center
318-
result.isHidden = call.hasConnected
319318

320319
if call.hasStartedConnecting { result.text = "callsConnecting".localized() }
321320

322321
return result
323322
}()
324323

324+
private lazy var callDetailedInfoLabel: UILabel = {
325+
let result: UILabel = UILabel()
326+
result.font = .boldSystemFont(ofSize: Values.smallFontSize)
327+
result.themeTextColor = .textPrimary
328+
result.textAlignment = .center
329+
330+
return result
331+
}()
332+
333+
private lazy var callInfoLabelStackView: UIStackView = {
334+
let result: UIStackView = UIStackView(arrangedSubviews: [callInfoLabel, callDetailedInfoLabel])
335+
result.axis = .vertical
336+
result.spacing = Values.mediumSpacing
337+
result.isHidden = call.hasConnected
338+
339+
return result
340+
}()
341+
325342
private lazy var callDurationLabel: UILabel = {
326343
let result = UILabel()
327344
result.font = .boldSystemFont(ofSize: Values.veryLargeFontSize)
@@ -350,11 +367,11 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
350367
remoteVideoView.alpha = isEnabled ? 1 : 0
351368
}
352369

353-
if self.callInfoLabel.alpha < 0.5 {
370+
if self.callInfoLabelStackView.alpha < 0.5 {
354371
UIView.animate(withDuration: 0.25) {
355372
self.operationPanel.alpha = 1
356373
self.responsePanel.alpha = 1
357-
self.callInfoLabel.alpha = 1
374+
self.callInfoLabelStackView.alpha = 1
358375
}
359376
}
360377
}
@@ -387,7 +404,7 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
387404
self?.durationTimer = Timer.scheduledTimer(withTimeInterval: 1, repeats: true) { _ in
388405
self?.updateDuration()
389406
}
390-
self?.callInfoLabel.isHidden = true
407+
self?.callInfoLabelStackView.isHidden = true
391408
self?.callDurationLabel.isHidden = false
392409
}
393410
}
@@ -402,18 +419,24 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
402419

403420
self.call.hasStartedReconnecting = { [weak self] in
404421
DispatchQueue.main.async {
405-
self?.callInfoLabel.isHidden = false
422+
self?.callInfoLabelStackView.isHidden = false
406423
self?.callDurationLabel.isHidden = true
407424
self?.callInfoLabel.text = "callsReconnecting".localized()
408425
}
409426
}
410427

411428
self.call.hasReconnected = { [weak self] in
412429
DispatchQueue.main.async {
413-
self?.callInfoLabel.isHidden = true
430+
self?.callInfoLabelStackView.isHidden = true
414431
self?.callDurationLabel.isHidden = false
415432
}
416433
}
434+
435+
self.call.updateCallDetailedStatus = { [weak self] status in
436+
DispatchQueue.main.async {
437+
self?.callDetailedInfoLabel.text = status
438+
}
439+
}
417440
}
418441

419442
required init(coder: NSCoder) { preconditionFailure("Use init(for:) instead.") }
@@ -510,10 +533,10 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
510533
callInfoLabelContainer.pin(.top, to: .bottom, of: profilePictureView)
511534
callInfoLabelContainer.pin(.bottom, to: .bottom, of: profilePictureContainer)
512535
callInfoLabelContainer.pin([ UIView.HorizontalEdge.left, UIView.HorizontalEdge.right ], to: view)
513-
callInfoLabelContainer.addSubview(callInfoLabel)
536+
callInfoLabelContainer.addSubview(callInfoLabelStackView)
514537
callInfoLabelContainer.addSubview(callDurationLabel)
515-
callInfoLabel.translatesAutoresizingMaskIntoConstraints = false
516-
callInfoLabel.center(in: callInfoLabelContainer)
538+
callInfoLabelStackView.translatesAutoresizingMaskIntoConstraints = false
539+
callInfoLabelStackView.center(in: callInfoLabelContainer)
517540
callDurationLabel.translatesAutoresizingMaskIntoConstraints = false
518541
callDurationLabel.center(in: callInfoLabelContainer)
519542
}
@@ -587,7 +610,7 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
587610

588611
func handleEndCallMessage() {
589612
SNLog("[Calls] Ending call.")
590-
self.callInfoLabel.isHidden = false
613+
self.callInfoLabelStackView.isHidden = false
591614
self.callDurationLabel.isHidden = true
592615
self.callInfoLabel.text = "callsEnded".localized()
593616

@@ -596,7 +619,7 @@ final class CallVC: UIViewController, VideoPreviewDelegate {
596619
remoteVideoView.alpha = 0
597620
self.operationPanel.alpha = 1
598621
self.responsePanel.alpha = 1
599-
self.callInfoLabel.alpha = 1
622+
self.callInfoLabelStackView.alpha = 1
600623
}
601624

602625
Timer.scheduledTimer(withTimeInterval: 2, repeats: false) { [weak self] _ in

Session/Calls/Views & Modals/IncomingCallBanner.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -204,8 +204,8 @@ final class IncomingCallBanner: UIView, UIGestureRecognizerDelegate {
204204
let callVC = CallVC(for: self.call)
205205
if let conversationVC = (presentingVC as? TopBannerController)?.wrappedViewController() as? ConversationVC {
206206
callVC.conversationVC = conversationVC
207-
conversationVC.inputAccessoryView?.isHidden = true
208-
conversationVC.inputAccessoryView?.alpha = 0
207+
conversationVC.resignFirstResponder()
208+
conversationVC.hideInputAccessoryView()
209209
}
210210

211211
presentingVC.present(callVC, animated: true) { [weak self] in

Session/Calls/WebRTC/WebRTCSession+MessageHandling.swift

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ extension WebRTCSession {
99

1010
public func handleICECandidates(_ candidate: [RTCIceCandidate]) {
1111
SNLog("[Calls] Received ICE candidate message.")
12+
self.delegate?.iceCandidateDidReceive()
1213
candidate.forEach { peerConnection?.add($0, completionHandler: { _ in }) }
1314
}
1415

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

25-
self?.sendAnswer(to: sessionId).sinkUntilComplete()
26+
self?.sendAnswer(to: sessionId)
27+
.retry(5)
28+
.sinkUntilComplete()
2629
}
2730
})
2831
}

Session/Calls/WebRTC/WebRTCSession.swift

Lines changed: 17 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ public protocol WebRTCSessionDelegate: AnyObject {
1212

1313
func webRTCIsConnected()
1414
func isRemoteVideoDidChange(isEnabled: Bool)
15+
func iceCandidateDidSend()
16+
func iceCandidateDidReceive()
1517
func dataChannelDidOpen()
1618
func didReceiveHangUpSignal()
1719
func reconnectIfNeeded()
@@ -339,9 +341,21 @@ public final class WebRTCSession : NSObject, RTCPeerConnectionDelegate {
339341
}
340342
.subscribe(on: DispatchQueue.global(qos: .userInitiated))
341343
.flatMap { [dependencies = self.dependencies] sendData in
342-
MessageSender.sendImmediate(data: sendData, using: dependencies)
344+
MessageSender
345+
.sendImmediate(data: sendData, using: dependencies)
346+
.retry(5)
343347
}
344-
.sinkUntilComplete()
348+
.sinkUntilComplete(
349+
receiveCompletion: { [weak self] result in
350+
switch result {
351+
case .finished:
352+
SNLog("[Calls] ICE candidates sent")
353+
self?.delegate?.iceCandidateDidSend()
354+
case .failure(let error):
355+
SNLog("[Calls] Error sending ICE candidates due to error: \(error)")
356+
}
357+
}
358+
)
345359
}
346360

347361
public func endCall(
@@ -375,6 +389,7 @@ public final class WebRTCSession : NSObject, RTCPeerConnectionDelegate {
375389
MessageSender
376390
.sendImmediate(data: preparedSendData, using: dependencies)
377391
.subscribe(on: DispatchQueue.global(qos: .userInitiated))
392+
.retry(5)
378393
.sinkUntilComplete()
379394
}
380395

0 commit comments

Comments
 (0)