From 44837b57e5229f1b992a82a9e77734f3c1788d46 Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Tue, 30 Nov 2021 11:48:04 +1100 Subject: [PATCH] improve the audio output device displaying --- Session/Calls/CallVC.swift | 48 +++++++++++++++++- .../Session/Airpods.imageset/Airpods.pdf | Bin 0 -> 5379 bytes .../Session/Airpods.imageset/Contents.json | 12 +++++ .../Session/Bluetooth.imageset/Bluetooth.pdf | Bin 0 -> 4041 bytes .../Session/Bluetooth.imageset/Contents.json | 12 +++++ .../Session/Headsets.imageset/Contents.json | 12 +++++ .../Session/Headsets.imageset/Headsets.pdf | Bin 0 -> 5286 bytes 7 files changed, 83 insertions(+), 1 deletion(-) create mode 100644 Session/Meta/Images.xcassets/Session/Airpods.imageset/Airpods.pdf create mode 100644 Session/Meta/Images.xcassets/Session/Airpods.imageset/Contents.json create mode 100644 Session/Meta/Images.xcassets/Session/Bluetooth.imageset/Bluetooth.pdf create mode 100644 Session/Meta/Images.xcassets/Session/Bluetooth.imageset/Contents.json create mode 100644 Session/Meta/Images.xcassets/Session/Headsets.imageset/Contents.json create mode 100644 Session/Meta/Images.xcassets/Session/Headsets.imageset/Headsets.pdf diff --git a/Session/Calls/CallVC.swift b/Session/Calls/CallVC.swift index af43db4f6..ab7a5f405 100644 --- a/Session/Calls/CallVC.swift +++ b/Session/Calls/CallVC.swift @@ -233,6 +233,11 @@ final class CallVC : UIViewController, VideoPreviewDelegate { } } } + NotificationCenter.default.addObserver(self, selector: #selector(audioRouteDidChange), name: AVAudioSession.routeChangeNotification, object: nil) + } + + deinit { + NotificationCenter.default.removeObserver(self) } func setUpViewHierarchy() { @@ -309,7 +314,7 @@ final class CallVC : UIViewController, VideoPreviewDelegate { if (call.isVideoEnabled && shouldRestartCamera) { cameraManager.stop() } } - // MARK: Interaction + // MARK: Call signalling func handleAnswerMessage(_ message: CallMessage) { callInfoLabel.text = "Connecting..." } @@ -351,6 +356,7 @@ final class CallVC : UIViewController, VideoPreviewDelegate { } } + // MARK: Minimize to a floating view @objc private func minimize() { self.shouldRestartCamera = false let miniCallView = MiniCallView(from: self) @@ -359,6 +365,7 @@ final class CallVC : UIViewController, VideoPreviewDelegate { presentingViewController?.dismiss(animated: true, completion: nil) } + // MARK: Video and Audio @objc private func operateCamera() { if (call.isVideoEnabled) { localVideoView.isHidden = true @@ -399,6 +406,45 @@ final class CallVC : UIViewController, VideoPreviewDelegate { } } + @objc private func audioRouteDidChange() { + let currentSession = AVAudioSession.sharedInstance() + let currentRoute = currentSession.currentRoute + if let currentOutput = currentRoute.outputs.first { + switch currentOutput.portType { + case .builtInReceiver: + let image = UIImage(named: "Speaker")?.withRenderingMode(.alwaysTemplate) + volumeView.setRouteButtonImage(image, for: .normal) + volumeView.tintColor = .white + volumeView.backgroundColor = UIColor(hex: 0x1F1F1F) + case .builtInSpeaker: + let image = UIImage(named: "Speaker")?.withRenderingMode(.alwaysTemplate) + volumeView.setRouteButtonImage(image, for: .normal) + volumeView.tintColor = UIColor(hex: 0x1F1F1F) + volumeView.backgroundColor = .white + case .headphones: + let image = UIImage(named: "Headsets")?.withRenderingMode(.alwaysTemplate) + volumeView.setRouteButtonImage(image, for: .normal) + volumeView.tintColor = UIColor(hex: 0x1F1F1F) + volumeView.backgroundColor = .white + case .bluetoothLE: fallthrough + case .bluetoothA2DP: + let image = UIImage(named: "Bluetooth")?.withRenderingMode(.alwaysTemplate) + volumeView.setRouteButtonImage(image, for: .normal) + volumeView.tintColor = UIColor(hex: 0x1F1F1F) + volumeView.backgroundColor = .white + case .bluetoothHFP: + let image = UIImage(named: "Airpods")?.withRenderingMode(.alwaysTemplate) + volumeView.setRouteButtonImage(image, for: .normal) + volumeView.tintColor = UIColor(hex: 0x1F1F1F) + volumeView.backgroundColor = .white + default: + break + } + } + print(currentRoute.outputs) + } + + // MARK: Pan gesture handling @objc private func handlePanGesture(gesture: UIPanGestureRecognizer) { let location = gesture.location(in: self.view) if let draggedView = gesture.view { diff --git a/Session/Meta/Images.xcassets/Session/Airpods.imageset/Airpods.pdf b/Session/Meta/Images.xcassets/Session/Airpods.imageset/Airpods.pdf new file mode 100644 index 0000000000000000000000000000000000000000..696a6fd4b67d3b17fccdfbb346d5092b8790badf GIT binary patch literal 5379 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 literal 0 HcmV?d00001 diff --git a/Session/Meta/Images.xcassets/Session/Airpods.imageset/Contents.json b/Session/Meta/Images.xcassets/Session/Airpods.imageset/Contents.json new file mode 100644 index 000000000..6bea31126 --- /dev/null +++ b/Session/Meta/Images.xcassets/Session/Airpods.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Airpods.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Session/Meta/Images.xcassets/Session/Bluetooth.imageset/Bluetooth.pdf b/Session/Meta/Images.xcassets/Session/Bluetooth.imageset/Bluetooth.pdf new file mode 100644 index 0000000000000000000000000000000000000000..d725fa2e49144448679d2d75bbe6fd6690d36b4d GIT binary patch literal 4041 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 literal 0 HcmV?d00001 diff --git a/Session/Meta/Images.xcassets/Session/Bluetooth.imageset/Contents.json b/Session/Meta/Images.xcassets/Session/Bluetooth.imageset/Contents.json new file mode 100644 index 000000000..d7ed33397 --- /dev/null +++ b/Session/Meta/Images.xcassets/Session/Bluetooth.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Bluetooth.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Session/Meta/Images.xcassets/Session/Headsets.imageset/Contents.json b/Session/Meta/Images.xcassets/Session/Headsets.imageset/Contents.json new file mode 100644 index 000000000..85eb7561e --- /dev/null +++ b/Session/Meta/Images.xcassets/Session/Headsets.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "filename" : "Headsets.pdf", + "idiom" : "universal" + } + ], + "info" : { + "author" : "xcode", + "version" : 1 + } +} diff --git a/Session/Meta/Images.xcassets/Session/Headsets.imageset/Headsets.pdf b/Session/Meta/Images.xcassets/Session/Headsets.imageset/Headsets.pdf new file mode 100644 index 0000000000000000000000000000000000000000..dd9cc0d4cb6ddd9c049615ef722b3167b848b4d1 GIT binary patch literal 5286 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 M9x5uTrmGJ957&y+bpQYW literal 0 HcmV?d00001