Skip to content
Snippets Groups Projects
Commit 384aebcd authored by Kateryna Kostiuk's avatar Kateryna Kostiuk Committed by Kateryna Kostiuk
Browse files

UI: update call view

Change-Id: I809dcb60e7a8322b9794adb0a07c4c30ab7cc81c
parent 978f8d2d
Branches
No related tags found
No related merge requests found
...@@ -22,31 +22,35 @@ import UIKit ...@@ -22,31 +22,35 @@ import UIKit
import Reusable import Reusable
import RxSwift import RxSwift
class ButtonsContainerView: UIView, NibLoadable { class ButtonsContainerView: UIView, NibLoadable, UIScrollViewDelegate {
//Outlets //Outlets
@IBOutlet var containerView: UIView! @IBOutlet var containerView: UIView!
@IBOutlet weak var container: UIView! @IBOutlet weak var container: UIView!
@IBOutlet weak var stackView: UIStackView! @IBOutlet weak var stackView: UIStackView!
@IBOutlet weak var firstPageStackView: UIStackView!
@IBOutlet weak var secondPageStackView: UIStackView!
@IBOutlet weak var backgroundBlurEffect: UIVisualEffectView! @IBOutlet weak var backgroundBlurEffect: UIVisualEffectView!
@IBOutlet weak var muteAudioButton: UIButton! @IBOutlet weak var cancelButton: UIButton! // cancel pending outgoing call
@IBOutlet weak var muteVideoButton: UIButton! @IBOutlet weak var pageControl: UIPageControl!
@IBOutlet weak var pauseCallButton: UIButton! @IBOutlet weak var scrollView: UIScrollView!
@IBOutlet weak var dialpadButton: UIButton!
@IBOutlet weak var switchSpeakerButton: UIButton!
@IBOutlet weak var cancelButton: UIButton!
@IBOutlet weak var switchCameraButton: UIButton!
@IBOutlet weak var acceptCallButton: UIButton!
//Constraints //Constraints
@IBOutlet weak var cancelButtonWidthConstraint: NSLayoutConstraint! @IBOutlet weak var cancelButtonWidthConstraint: NSLayoutConstraint!
@IBOutlet weak var cancelButtonCenterConstraint: NSLayoutConstraint!
@IBOutlet weak var cancelButtonBottomConstraint: NSLayoutConstraint!
@IBOutlet weak var cancelButtonHeightConstraint: NSLayoutConstraint! @IBOutlet weak var cancelButtonHeightConstraint: NSLayoutConstraint!
@IBOutlet weak var stackViewYConstraint: NSLayoutConstraint! @IBOutlet weak var cancelButtonBottomConstraint: NSLayoutConstraint!
@IBOutlet weak var stackViewWidthConstraint: NSLayoutConstraint!
@IBOutlet weak var containerHeightConstraint: NSLayoutConstraint! @IBOutlet weak var containerHeightConstraint: NSLayoutConstraint!
//Buttons
var muteAudioButton: UIButton!
var muteVideoButton: UIButton!
var pauseCallButton: UIButton!
var dialpadButton: UIButton!
var stopButton: UIButton! // stop current call
var switchCameraButton: UIButton!
var switchSpeakerButton: UIButton!
var addParticipantButton: UIButton!
let disposeBag = DisposeBag() let disposeBag = DisposeBag()
var isCallStarted: Bool = false var isCallStarted: Bool = false
...@@ -59,9 +63,9 @@ class ButtonsContainerView: UIView, NibLoadable { ...@@ -59,9 +63,9 @@ class ButtonsContainerView: UIView, NibLoadable {
case .none: case .none:
self?.withoutOptions() self?.withoutOptions()
case .optionsWithoutSpeakerphone: case .optionsWithoutSpeakerphone:
self?.optionsWithoutSpeaker() self?.update(withSpeakerEnable: false)
case .optionsWithSpeakerphone: case .optionsWithSpeakerphone:
self?.optionsWithSpeaker() self?.update(withSpeakerEnable: true)
} }
}) })
.disposed(by: self.disposeBag) .disposed(by: self.disposeBag)
...@@ -81,6 +85,7 @@ class ButtonsContainerView: UIView, NibLoadable { ...@@ -81,6 +85,7 @@ class ButtonsContainerView: UIView, NibLoadable {
override func didMoveToWindow() { override func didMoveToWindow() {
super.didMoveToWindow() super.didMoveToWindow()
self.cancelButton.backgroundColor = UIColor.red self.cancelButton.backgroundColor = UIColor.red
self.stopButton.backgroundColor = UIColor.red
} }
func commonInit() { func commonInit() {
...@@ -88,93 +93,106 @@ class ButtonsContainerView: UIView, NibLoadable { ...@@ -88,93 +93,106 @@ class ButtonsContainerView: UIView, NibLoadable {
addSubview(containerView) addSubview(containerView)
containerView.frame = self.bounds containerView.frame = self.bounds
self.container.clipsToBounds = false self.container.clipsToBounds = false
scrollView.delegate = self
muteAudioButton = configureButton(image: UIImage(asset: Asset.audioMuted))
muteVideoButton = configureButton(image: UIImage(asset: Asset.videoMuted))
pauseCallButton = configureButton(image: UIImage(asset: Asset.pauseCall))
dialpadButton = configureButton(image: UIImage(asset: Asset.dialpad))
stopButton = configureButton(image: UIImage(asset: Asset.stopCall))
stopButton.borderColor = UIColor.red
switchCameraButton = configureButton(image: UIImage(asset: Asset.switchCamera))
switchSpeakerButton = configureButton(image: UIImage(asset: Asset.enableSpeakerphone))
addParticipantButton = configureButton(image: UIImage(asset: Asset.addPerson))
pageControl.addTarget(self, action: #selector(changePage), for: UIControl.Event.valueChanged)
}
func configureButton(image: UIImage?) -> UIButton {
let button = UIButton()
button.heightAnchor.constraint(equalToConstant: 50).isActive = true
button.widthAnchor.constraint(equalToConstant: 50).isActive = true
button.cornerRadius = 25
button.borderWidth = 1
button.borderColor = UIColor.white
button.tintColor = UIColor.white
button.setImage(image, for: .normal)
return button
} }
func withoutOptions() { func withoutOptions() {
self.container.backgroundColor = UIColor.clear self.container.backgroundColor = UIColor.clear
self.backgroundBlurEffect.isHidden = true self.backgroundBlurEffect.isHidden = true
switchCameraButton.isHidden = true
muteAudioButton.isHidden = true
muteVideoButton.isHidden = true
pauseCallButton.isHidden = true
dialpadButton.isHidden = true
switchSpeakerButton.isHidden = true
cancelButton.isHidden = false cancelButton.isHidden = false
firstPageStackView.removeSubviews()
secondPageStackView.removeSubviews()
pageControl.isHidden = true
if self.viewModel?.isIncoming ?? false { if self.viewModel?.isIncoming ?? false {
acceptCallButton.isHidden = false
cancelButtonBottomConstraint.constant = 60 cancelButtonBottomConstraint.constant = 60
cancelButtonCenterConstraint.constant = -80
return return
} }
cancelButtonCenterConstraint.constant = 0
cancelButtonBottomConstraint.constant = 20 cancelButtonBottomConstraint.constant = 20
scrollView.isScrollEnabled = false
} }
func optionsWithSpeaker() { func update(withSpeakerEnable enable: Bool) {
acceptCallButton.isHidden = true
cancelButtonCenterConstraint.constant = 0
self.backgroundBlurEffect.isHidden = false self.backgroundBlurEffect.isHidden = false
muteAudioButton.isHidden = false cancelButton.isHidden = true
if self.viewModel?.isAudioOnly ?? false { switchSpeakerButton.isEnabled = enable
muteVideoButton.isHidden = true let isSip = self.viewModel?.isSipCall ?? false
switchCameraButton.isHidden = true let audioOnly = self.viewModel?.isAudioOnly ?? false
if self.viewModel?.isSipCall ?? false { var havePages = false
dialpadButton.isHidden = false if isSip {
} firstPageStackView.removeSubviews()
cancelButtonBottomConstraint.constant = 20 secondPageStackView.removeSubviews()
firstPageStackView.addArrangedSubview(stopButton)
firstPageStackView.addArrangedSubview(pauseCallButton)
firstPageStackView.addArrangedSubview(muteAudioButton)
firstPageStackView.addArrangedSubview(switchSpeakerButton)
firstPageStackView.addArrangedSubview(dialpadButton)
} else if audioOnly {
firstPageStackView.removeSubviews()
secondPageStackView.removeSubviews()
firstPageStackView.addArrangedSubview(stopButton)
firstPageStackView.addArrangedSubview(pauseCallButton)
firstPageStackView.addArrangedSubview(muteAudioButton)
firstPageStackView.addArrangedSubview(switchSpeakerButton)
firstPageStackView.addArrangedSubview(addParticipantButton)
} else { } else {
muteVideoButton.isHidden = false let screenRect = UIScreen.main.bounds
switchCameraButton.isHidden = false let screenWidth: CGFloat = screenRect.size.width
cancelButtonBottomConstraint.constant = 80 let buttonsWidth: CGFloat = 7 * 50 + 30 * 6 //540
havePages = screenWidth < buttonsWidth
firstPageStackView.removeSubviews()
secondPageStackView.removeSubviews()
firstPageStackView.addArrangedSubview(stopButton)
firstPageStackView.addArrangedSubview(pauseCallButton)
firstPageStackView.addArrangedSubview(switchCameraButton)
firstPageStackView.addArrangedSubview(switchSpeakerButton)
firstPageStackView.addArrangedSubview(addParticipantButton)
if havePages {
secondPageStackView.addArrangedSubview(muteAudioButton)
secondPageStackView.addArrangedSubview(muteVideoButton)
} else {
firstPageStackView.addArrangedSubview(muteAudioButton)
firstPageStackView.addArrangedSubview(muteVideoButton)
} }
pauseCallButton.isHidden = false
switchSpeakerButton.isEnabled = true
switchSpeakerButton.isHidden = false
cancelButton.isHidden = false
setUpConference()
setButtonsColor()
} }
pageControl.isHidden = !havePages
func optionsWithoutSpeaker() { scrollView.isScrollEnabled = havePages
acceptCallButton.isHidden = true
cancelButtonCenterConstraint.constant = 0
if self.viewModel?.isAudioOnly ?? false { if self.viewModel?.isAudioOnly ?? false {
muteVideoButton.isHidden = true
switchCameraButton.isHidden = true
if self.viewModel?.isSipCall ?? false {
dialpadButton.isHidden = false
}
cancelButtonBottomConstraint.constant = 20 cancelButtonBottomConstraint.constant = 20
} else { } else {
switchCameraButton.isHidden = false
muteVideoButton.isHidden = false
cancelButtonBottomConstraint.constant = 80 cancelButtonBottomConstraint.constant = 80
} }
switchSpeakerButton.isEnabled = false
self.muteAudioButton.isHidden = false
switchSpeakerButton.isHidden = false
self.backgroundBlurEffect.isHidden = false
pauseCallButton.isHidden = false
cancelButton.isHidden = false
setUpConference()
setButtonsColor() setButtonsColor()
} }
func setUpConference() {
if !(self.viewModel?.isConference ?? false) {
return
}
pauseCallButton.isHidden = true
muteAudioButton.isHidden = true
muteVideoButton.isHidden = true
cancelButtonBottomConstraint.constant = 0
}
func updateView() { func updateView() {
if switchSpeakerButton.isEnabled && !switchSpeakerButton.isHidden { if firstPageStackView.subviews.isEmpty {
self.optionsWithSpeaker() self.withoutOptions()
} else if switchSpeakerButton.isEnabled && !switchSpeakerButton.isHidden {
self.update(withSpeakerEnable: true)
} else if !switchSpeakerButton.isHidden { } else if !switchSpeakerButton.isHidden {
self.optionsWithoutSpeaker() self.update(withSpeakerEnable: false)
} }
} }
...@@ -202,4 +220,16 @@ class ButtonsContainerView: UIView, NibLoadable { ...@@ -202,4 +220,16 @@ class ButtonsContainerView: UIView, NibLoadable {
muteVideoButton.borderColor = UIColor.white muteVideoButton.borderColor = UIColor.white
switchCameraButton.tintColor = UIColor.white switchCameraButton.tintColor = UIColor.white
} }
@objc
func changePage(sender: AnyObject) {
let xpoint = CGFloat(pageControl.currentPage) * scrollView.frame.size.width
scrollView.setContentOffset(CGPoint(x: xpoint, y: 0), animated: true)
}
func scrollViewDidEndDecelerating(_ scrollView: UIScrollView) {
let pageNumber = round(scrollView.contentOffset.x / scrollView.frame.size.width)
pageControl.currentPage = Int(pageNumber)
}
} }
This diff is collapsed.
This diff is collapsed.
...@@ -49,7 +49,6 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con ...@@ -49,7 +49,6 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con
@IBOutlet weak var capturedVideoBlurEffect: UIVisualEffectView! @IBOutlet weak var capturedVideoBlurEffect: UIVisualEffectView!
@IBOutlet weak var viewCapturedVideo: UIView! @IBOutlet weak var viewCapturedVideo: UIView!
@IBOutlet private weak var infoContainer: UIView! @IBOutlet private weak var infoContainer: UIView!
//@IBOutlet private weak var callProfileImage: UIImageView!
@IBOutlet private weak var callNameLabel: UILabel! @IBOutlet private weak var callNameLabel: UILabel!
@IBOutlet private weak var callInfoTimerLabel: UILabel! @IBOutlet private weak var callInfoTimerLabel: UILabel!
@IBOutlet private weak var buttonsContainer: ButtonsContainerView! @IBOutlet private weak var buttonsContainer: ButtonsContainerView!
...@@ -74,8 +73,6 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con ...@@ -74,8 +73,6 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con
@IBOutlet weak var conferenceLayout: ConferenceLayout! @IBOutlet weak var conferenceLayout: ConferenceLayout!
@IBOutlet weak var sendMessageButton: UIButton! @IBOutlet weak var sendMessageButton: UIButton!
@IBOutlet weak var inConferenceAddContactButton: UIView!
@IBOutlet weak var conferenceCallsLeading: NSLayoutConstraint!
@IBOutlet weak var conferenceCallsTop: NSLayoutConstraint! @IBOutlet weak var conferenceCallsTop: NSLayoutConstraint!
var viewModel: CallViewModel! var viewModel: CallViewModel!
...@@ -124,7 +121,6 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con ...@@ -124,7 +121,6 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con
UIApplication.shared.isIdleTimerDisabled = true UIApplication.shared.isIdleTimerDisabled = true
initCallAnimation() initCallAnimation()
self.configureConferenceLayout() self.configureConferenceLayout()
self.inConferenceAddContactButton.isHidden = !self.viewModel.conferenceMode.value
if callCurrent { if callCurrent {
self.capturedVideoBlurEffect.alpha = 1 self.capturedVideoBlurEffect.alpha = 1
hideCapturedVideo() hideCapturedVideo()
...@@ -146,14 +142,6 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con ...@@ -146,14 +142,6 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con
buttonsStackView.isHidden = self.viewModel.isBoothMode() buttonsStackView.isHidden = self.viewModel.isBoothMode()
} }
@IBAction func addParticipant(_ sender: Any) {
let children = self.children
for child in children where child.isKind(of: (ContactPickerViewController).self) {
return
}
self.viewModel.showContactPickerVC()
}
func addTapGesture() { func addTapGesture() {
self.mainView.addGestureRecognizer(tapGestureRecognizer) self.mainView.addGestureRecognizer(tapGestureRecognizer)
} }
...@@ -237,19 +225,16 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con ...@@ -237,19 +225,16 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con
self?.removeFromScreen() self?.removeFromScreen()
}) })
.disposed(by: self.disposeBag) .disposed(by: self.disposeBag)
self.sendMessageButton.rx.tap self.buttonsContainer.stopButton.rx.tap
.subscribe(onNext: { [weak self] in .subscribe(onNext: { [weak self] in
self?.viewModel.showConversations() self?.viewModel.cancelCall(stopProvider: true)
self?.dismiss(animated: false, completion: nil) self?.removeFromScreen()
}) })
.disposed(by: self.disposeBag) .disposed(by: self.disposeBag)
self.sendMessageButton.rx.tap
self.buttonsContainer.acceptCallButton.rx.tap
.subscribe(onNext: { [weak self] in .subscribe(onNext: { [weak self] in
guard let self = self else { return } self?.viewModel.showConversations()
self.viewModel.answerCall() self?.dismiss(animated: false, completion: nil)
.subscribe()
.disposed(by: self.disposeBag)
}) })
.disposed(by: self.disposeBag) .disposed(by: self.disposeBag)
...@@ -290,7 +275,16 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con ...@@ -290,7 +275,16 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con
self?.viewModel.switchSpeaker() self?.viewModel.switchSpeaker()
}) })
.disposed(by: self.disposeBag) .disposed(by: self.disposeBag)
self.buttonsContainer.addParticipantButton.rx.tap
.subscribe(onNext: { [weak self] in
guard let self = self else { return }
let children = self.children
for child in children where child.isKind(of: (ContactPickerViewController).self) {
return
}
self.viewModel.showContactPickerVC()
})
.disposed(by: self.disposeBag)
//Data bindings //Data bindings
self.viewModel.videoButtonState self.viewModel.videoButtonState
.observeOn(MainScheduler.instance) .observeOn(MainScheduler.instance)
...@@ -356,8 +350,6 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con ...@@ -356,8 +350,6 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con
if self?.viewModel.isAudioOnly ?? true { if self?.viewModel.isAudioOnly ?? true {
self?.buttonContainerHeightConstraint.constant = 200 self?.buttonContainerHeightConstraint.constant = 200
self?.buttonsContainer.containerHeightConstraint.constant = 200 self?.buttonsContainer.containerHeightConstraint.constant = 200
self?.buttonsContainer.stackViewYConstraint.constant = 110
self?.buttonsContainer.stackViewWidthConstraint.priority = UILayoutPriority(rawValue: 999)
UIView.animate(withDuration: 0.3, animations: { UIView.animate(withDuration: 0.3, animations: {
self?.durationLabel.alpha = 1 self?.durationLabel.alpha = 1
self?.buttonsContainer.stackView.alpha = 1 self?.buttonsContainer.stackView.alpha = 1
...@@ -461,25 +453,23 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con ...@@ -461,25 +453,23 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con
self?.buttonsContainer.updateView() self?.buttonsContainer.updateView()
self?.infoContainer.isHidden = enteredConference ? true : false self?.infoContainer.isHidden = enteredConference ? true : false
self?.resizeCapturedVideo(withInfoContainer: false) self?.resizeCapturedVideo(withInfoContainer: false)
self?.inConferenceAddContactButton.isHidden = !enteredConference
self?.conferenceCallsLeading.constant = enteredConference ? 0 : -80
// if entered conference add first participant to conference list // if entered conference add first participant to conference list
if enteredConference { if enteredConference {
self?.removeConferenceParticipantMenu() self?.removeConferenceParticipantMenu()
guard let injectionBag = self?.viewModel.injectionBag guard let injectionBag = self?.viewModel.injectionBag
else { return } else { return }
// add self as a master call // add self as a master call
let masterCallView = let mainCallView =
ConferenceParticipantView(frame: CGRect(x: 0, ConferenceParticipantView(frame: CGRect(x: 0,
y: 0, y: 0,
width: inConfViewWidth, width: inConfViewWidth,
height: inConfViewHeight)) height: inConfViewHeight))
let masterCallViewModel = let mainCallViewModel =
ConferenceParticipantViewModel(with: nil, ConferenceParticipantViewModel(with: nil,
injectionBag: injectionBag) injectionBag: injectionBag)
masterCallView.viewModel = masterCallViewModel mainCallView.viewModel = mainCallViewModel
masterCallView.delegate = self mainCallView.delegate = self
self?.conferenceCalls.insertArrangedSubview(masterCallView, at: 0) self?.conferenceCalls.insertArrangedSubview(mainCallView, at: 0)
let callView = let callView =
ConferenceParticipantView(frame: CGRect(x: 0, ConferenceParticipantView(frame: CGRect(x: 0,
y: 0, y: 0,
...@@ -642,6 +632,7 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con ...@@ -642,6 +632,7 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con
DispatchQueue.main.async { [weak self] in DispatchQueue.main.async { [weak self] in
//guard let hidden = self?.infoContainer.isHidden else {return} //guard let hidden = self?.infoContainer.isHidden else {return}
self?.resizeCapturedVideo(withInfoContainer: false) self?.resizeCapturedVideo(withInfoContainer: false)
self?.buttonsContainer.updateView()
if UIDevice.current.hasNotch && (UIDevice.current.orientation == .landscapeRight || UIDevice.current.orientation == .landscapeLeft) && self?.infoContainer.isHidden == false { if UIDevice.current.hasNotch && (UIDevice.current.orientation == .landscapeRight || UIDevice.current.orientation == .landscapeLeft) && self?.infoContainer.isHidden == false {
self?.buttonsContainerBottomConstraint.constant = 1 self?.buttonsContainerBottomConstraint.constant = 1
} }
...@@ -733,7 +724,6 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con ...@@ -733,7 +724,6 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con
self.infoContainer.isHidden = false self.infoContainer.isHidden = false
} else { } else {
self.conferenceCallsScrolView.isHidden = false self.conferenceCallsScrolView.isHidden = false
self.inConferenceAddContactButton.isHidden = false
} }
self.view.layoutIfNeeded() self.view.layoutIfNeeded()
...@@ -763,7 +753,6 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con ...@@ -763,7 +753,6 @@ class CallViewController: UIViewController, StoryboardBased, ViewModelBased, Con
self?.infoContainer.isHidden = true self?.infoContainer.isHidden = true
} else { } else {
self?.conferenceCallsScrolView.isHidden = true self?.conferenceCallsScrolView.isHidden = true
self?.inConferenceAddContactButton.isHidden = true
} }
self?.buttonsContainer.isHidden = true self?.buttonsContainer.isHidden = true
}) })
......
...@@ -141,7 +141,7 @@ class ContactPickerViewController: UIViewController, StoryboardBased, ViewModelB ...@@ -141,7 +141,7 @@ class ContactPickerViewController: UIViewController, StoryboardBased, ViewModelB
var contact = contactItem.contacts.first! var contact = contactItem.contacts.first!
cell.nameLabel.text = contact.firstLine cell.nameLabel.text = contact.firstLine
cell.lastMessagePreviewLabel?.text = contact.secondLine cell.lastMessagePreviewLabel?.isHidden = true
var imageData: Data? var imageData: Data?
if let contactProfile = contact.profile, let photo = contactProfile.photo, if let contactProfile = contact.profile, let photo = contactProfile.photo,
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment