From 18453405822470fa42a061f0da7a8211ce43f62c Mon Sep 17 00:00:00 2001 From: Ryan Zhao Date: Mon, 13 Feb 2023 14:22:54 +1100 Subject: [PATCH] WIP: refactor on the call UI to add switching function of caller and callee's video views --- .../Calls/Call Management/SessionCall.swift | 4 + Session/Calls/CallVC.swift | 88 +++++++++++++++++-- .../Calls/Views & Modals/CallVideoView.swift | 5 +- .../Calls/WebRTCSession+UI.swift | 4 + 4 files changed, 90 insertions(+), 11 deletions(-) diff --git a/Session/Calls/Call Management/SessionCall.swift b/Session/Calls/Call Management/SessionCall.swift index 4c3250429..de3f64f48 100644 --- a/Session/Calls/Call Management/SessionCall.swift +++ b/Session/Calls/Call Management/SessionCall.swift @@ -356,6 +356,10 @@ public final class SessionCall: CurrentCallProtocol, WebRTCSessionDelegate { webRTCSession.attachLocalRenderer(renderer) } + func removeLocalVideoRenderer(_ renderer: RTCVideoRenderer) { + webRTCSession.removeLocalRenderer(renderer) + } + // MARK: - Delegate public func webRTCIsConnected() { diff --git a/Session/Calls/CallVC.swift b/Session/Calls/CallVC.swift index 49152e981..cc6609c5e 100644 --- a/Session/Calls/CallVC.swift +++ b/Session/Calls/CallVC.swift @@ -8,6 +8,9 @@ import SessionMessagingKit import SessionUtilitiesKit final class CallVC: UIViewController, VideoPreviewDelegate { + static let floatingVideoViewWidth: CGFloat = UIDevice.current.isIPad ? 160 : 80 + static let floatingVideoViewHeight: CGFloat = UIDevice.current.isIPad ? 346: 173 + let call: SessionCall var latestKnownAudioOutputDeviceName: String? var durationTimer: Timer? @@ -23,25 +26,92 @@ final class CallVC: UIViewController, VideoPreviewDelegate { // MARK: - UI Components - private lazy var localVideoView: LocalVideoView = { + private lazy var floatingLocalVideoView: LocalVideoView = { let result = LocalVideoView() result.clipsToBounds = true result.themeBackgroundColor = .backgroundSecondary result.isHidden = !call.isVideoEnabled result.layer.cornerRadius = UIDevice.current.isIPad ? 20 : 10 result.layer.masksToBounds = true - result.set(.width, to: LocalVideoView.width) - result.set(.height, to: LocalVideoView.height) - result.makeViewDraggable() + result.set(.width, to: Self.floatingVideoViewWidth) + result.set(.height, to: Self.floatingVideoViewHeight) + + return result + }() + + private lazy var floatingRemoteVideoView: RemoteVideoView = { + let result = RemoteVideoView() + result.clipsToBounds = true + result.themeBackgroundColor = .backgroundSecondary + result.layer.cornerRadius = UIDevice.current.isIPad ? 20 : 10 + result.layer.masksToBounds = true + result.set(.width, to: Self.floatingVideoViewWidth) + result.set(.height, to: Self.floatingVideoViewHeight) return result }() - private lazy var remoteVideoView: RemoteVideoView = { + private lazy var fullScreenLocalVideoView: LocalVideoView = { + let result = LocalVideoView() + result.alpha = 0 + result.themeBackgroundColor = .backgroundPrimary + result.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleFullScreenVideoViewTapped))) + + return result + }() + + private lazy var fullScreenRemoteVideoView: RemoteVideoView = { let result = RemoteVideoView() result.alpha = 0 result.themeBackgroundColor = .backgroundPrimary - result.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleRemoteVieioViewTapped))) + result.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(handleFullScreenVideoViewTapped))) + + return result + }() + + private lazy var switchVideoButton: UIButton = { + let result = UIButton(type: .custom) + result.setImage( + UIImage(named: "ic_switch_camera")? + .withRenderingMode(.alwaysTemplate), + for: .normal + ) + result.themeTintColor = .textPrimary + result.addTarget(self, action: #selector(switchVideo), for: UIControl.Event.touchUpInside) + result.set(.width, to: 20) + result.set(.height, to: 20) + + return result + }() + + private lazy var switchVideoButtonContainer: UIView = { + let result = UIView() + result.themeBackgroundColor = .backgroundPrimary + result.layer.cornerRadius = UIDevice.current.isIPad ? 12 : 6 + result.layer.masksToBounds = true + result.addSubview(switchVideoButton) + switchVideoButton.pin(.leading, to: .leading, of: result, withInset: Values.smallSpacing) + switchVideoButton.pin(.trailing, to: .trailing, of: result, withInset: Values.smallSpacing) + switchVideoButton.pin(.bottom, to: .bottom, of: result, withInset: Values.smallSpacing) + switchVideoButton.pin(.top, to: .top, of: result, withInset: Values.largeSpacing) + + return result + }() + + private lazy var floatingViewContainer: UIView = { + let result = UIView() + result.makeViewDraggable() + result.addSubview(switchVideoButtonContainer) + switchVideoButtonContainer.pin(.trailing, to: .trailing, of: result) + switchVideoButtonContainer.pin(.bottom, to: .bottom, of: result) + + result.addSubview(floatingLocalVideoView) + floatingLocalVideoView.pin([ UIView.HorizontalEdge.leading, UIView.HorizontalEdge.trailing, UIView.VerticalEdge.top], to: result) + floatingLocalVideoView.pin(.bottom, to: .bottom, of: result, withInset: 36) + + result.addSubview(floatingRemoteVideoView) + floatingRemoteVideoView.pin([ UIView.HorizontalEdge.leading, UIView.HorizontalEdge.trailing, UIView.VerticalEdge.top], to: result) + floatingRemoteVideoView.pin(.bottom, to: .bottom, of: result, withInset: 36) return result }() @@ -584,6 +654,10 @@ final class CallVC: UIViewController, VideoPreviewDelegate { call.isVideoEnabled = true } + @objc private func switchVideo() { + + } + @objc private func switchCamera() { cameraManager.switchCamera() } @@ -645,7 +719,7 @@ final class CallVC: UIViewController, VideoPreviewDelegate { } } - @objc private func handleRemoteVieioViewTapped(gesture: UITapGestureRecognizer) { + @objc private func handleFullScreenVideoViewTapped(gesture: UITapGestureRecognizer) { let isHidden = callDurationLabel.alpha < 0.5 UIView.animate(withDuration: 0.5) { diff --git a/Session/Calls/Views & Modals/CallVideoView.swift b/Session/Calls/Views & Modals/CallVideoView.swift index 899732f66..d2e8894c0 100644 --- a/Session/Calls/Views & Modals/CallVideoView.swift +++ b/Session/Calls/Views & Modals/CallVideoView.swift @@ -87,10 +87,7 @@ class RemoteVideoView: TargetView { // MARK: LocalVideoView class LocalVideoView: TargetView { - - static let width: CGFloat = UIDevice.current.isIPad ? 160 : 80 - static let height: CGFloat = UIDevice.current.isIPad ? 346: 173 - + override func renderFrame(_ frame: RTCVideoFrame?) { super.renderFrame(frame) DispatchMainThreadSafe { diff --git a/SessionMessagingKit/Calls/WebRTCSession+UI.swift b/SessionMessagingKit/Calls/WebRTCSession+UI.swift index 305d1bfb7..2594d8a15 100644 --- a/SessionMessagingKit/Calls/WebRTCSession+UI.swift +++ b/SessionMessagingKit/Calls/WebRTCSession+UI.swift @@ -6,6 +6,10 @@ extension WebRTCSession { localVideoTrack.add(renderer) } + public func removeLocalRenderer(_ renderer: RTCVideoRenderer) { + localVideoTrack.remove(renderer) + } + public func attachRemoteRenderer(_ renderer: RTCVideoRenderer) { remoteVideoTrack?.add(renderer) }