|
@@ -20,7 +20,7 @@ class QmeraVideoViewController: UIViewController {
|
|
|
var fPin = ""
|
|
|
var wbRoomId = ""
|
|
|
var isInisiator = true
|
|
|
- var isSpeaker = false
|
|
|
+ var isSpeaker = true
|
|
|
var listRemoteViewFix: [UIImageView] = [
|
|
|
UIImageView(),
|
|
|
UIImageView(),
|
|
@@ -54,6 +54,7 @@ class QmeraVideoViewController: UIViewController {
|
|
|
var wbVC : WhiteboardViewController?
|
|
|
let buttonAddParticipant = UIButton()
|
|
|
let buttonSpeaker = UIButton()
|
|
|
+ let buttonRotate = UIButton()
|
|
|
var showStackViewToolbar = true
|
|
|
let scrollRemoteView = UIScrollView()
|
|
|
var isAutoAccept = false
|
|
@@ -62,6 +63,7 @@ class QmeraVideoViewController: UIViewController {
|
|
|
var showNotifCCEnd = false
|
|
|
var transformZoomAfterNewUserMore2 = false
|
|
|
var isAddCall = ""
|
|
|
+ private var frontCamera = true
|
|
|
var users: [User] = []
|
|
|
let poweredByView: UIStackView = {
|
|
|
let stackView = UIStackView()
|
|
@@ -102,6 +104,19 @@ class QmeraVideoViewController: UIViewController {
|
|
|
return button
|
|
|
}()
|
|
|
|
|
|
+ deinit {
|
|
|
+ self.wbTimer.invalidate()
|
|
|
+ navigationController?.navigationBar.setBackgroundImage(nil, for: .default)
|
|
|
+ navigationController?.navigationBar.shadowImage = nil
|
|
|
+ navigationController?.navigationBar.isTranslucent = false
|
|
|
+ navigationController?.view.backgroundColor = .mainColor
|
|
|
+ let textAttributes = [NSAttributedString.Key.foregroundColor:UIColor.white]
|
|
|
+ navigationController?.navigationBar.titleTextAttributes = textAttributes
|
|
|
+ navigationController?.navigationBar.topItem?.backBarButtonItem = nil
|
|
|
+ navigationController?.interactivePopGestureRecognizer?.isEnabled = true
|
|
|
+ NotificationCenter.default.removeObserver(self)
|
|
|
+ }
|
|
|
+
|
|
|
override func viewWillDisappear(_ animated: Bool) {
|
|
|
if self.isMovingFromParent {
|
|
|
navigationController?.navigationBar.setBackgroundImage(nil, for: .default)
|
|
@@ -164,9 +179,42 @@ class QmeraVideoViewController: UIViewController {
|
|
|
row["deviceId"] = cursorData.string(forColumnIndex: 5)
|
|
|
row["isOffline"] = cursorData.string(forColumnIndex: 6)
|
|
|
row["user_type"] = cursorData.string(forColumnIndex: 7)
|
|
|
+ dataPerson.append(row)
|
|
|
+ } else {
|
|
|
+ var row: [String: String?] = [:]
|
|
|
+ row["f_pin"] = fPin
|
|
|
+ row["name"] = "User".localized()
|
|
|
+ row["picture"] = ""
|
|
|
+ row["isOfficial"] = ""
|
|
|
+ row["deviceId"] = ""
|
|
|
+ row["isOffline"] = ""
|
|
|
+ row["user_type"] = ""
|
|
|
+ dataPerson.append(row)
|
|
|
}
|
|
|
- dataPerson.append(row)
|
|
|
cursorData.close()
|
|
|
+ } else {
|
|
|
+ var row: [String: String?] = [:]
|
|
|
+ row["f_pin"] = fPin
|
|
|
+ row["name"] = "User".localized()
|
|
|
+ row["picture"] = ""
|
|
|
+ row["isOfficial"] = ""
|
|
|
+ row["deviceId"] = ""
|
|
|
+ row["isOffline"] = ""
|
|
|
+ row["user_type"] = ""
|
|
|
+ dataPerson.append(row)
|
|
|
+// if let response = Nexilis.writeAndWait(message: CoreMessage_TMessageBank.getAddFriendQRCode(fpin: fPin)), response.isOk() {
|
|
|
+// self.getDataProfile(fPin: fPin)
|
|
|
+// }
|
|
|
+// Nexilis.addFriend (fpin: "\(fPin)") { result in
|
|
|
+// if result {
|
|
|
+// self.getDataProfile(fPin: fPin)
|
|
|
+// } else {
|
|
|
+// let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
|
|
|
+// imageView.tintColor = .white
|
|
|
+// let banner = FloatingNotificationBanner(title: "Server busy, please try again later".localized(), subtitle: nil, titleFont: UIFont.systemFont(ofSize: 16), titleColor: nil, titleTextAlign: .left, subtitleFont: nil, subtitleColor: nil, subtitleTextAlign: nil, leftView: imageView, rightView: nil, style: .danger, colors: nil, iconPosition: .center)
|
|
|
+// banner.show()
|
|
|
+// }
|
|
|
+// }
|
|
|
}
|
|
|
})
|
|
|
}
|
|
@@ -297,6 +345,7 @@ class QmeraVideoViewController: UIViewController {
|
|
|
])
|
|
|
if isInisiator {
|
|
|
labelIncomingOutgoing.text = "Outgoing video call".localized() + "..."
|
|
|
+ Nexilis.startAudio(nMode: 2, bSpeakerOn: true)
|
|
|
API.initiateCCall(sParty: dataPerson[0]["f_pin"]!, nCamIdx: 1, nResIdx: 2, nVQuality: 2, ivRemoteView: listRemoteViewFix, ivLocalView: cameraView, ivRemoteZ: zoomView)
|
|
|
} else {
|
|
|
let systemSoundID: SystemSoundID = 1254
|
|
@@ -380,7 +429,7 @@ class QmeraVideoViewController: UIViewController {
|
|
|
dataPerson["name"] = user.fullName
|
|
|
dataPerson["picture"] = user.thumb
|
|
|
dataPerson["isOfficial"] = user.official
|
|
|
- dataPerson["deviceId"] = ""
|
|
|
+ dataPerson["deviceId"] = user.pin
|
|
|
dataPerson["isOffline"] = ""
|
|
|
dataPerson["user_type"] = user.userType
|
|
|
self.dataPerson.append(dataPerson)
|
|
@@ -419,6 +468,7 @@ class QmeraVideoViewController: UIViewController {
|
|
|
}
|
|
|
|
|
|
@objc func didTapAcceptCallButton(){
|
|
|
+ Nexilis.startAudio(nMode: 2, bSpeakerOn: true)
|
|
|
API.receiveCCall(sParty: dataPerson[0]["f_pin"]!, nCamIdx: 1, nResIdx: 2, nVQuality: 4, ivRemoteView: listRemoteViewFix, ivLocalView: cameraView,ivRemoteZ: zoomView)
|
|
|
DispatchQueue.main.async {
|
|
|
self.myImage.removeFromSuperview()
|
|
@@ -436,6 +486,7 @@ class QmeraVideoViewController: UIViewController {
|
|
|
self.view.layoutIfNeeded()
|
|
|
})
|
|
|
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
|
|
|
+ self.buttonRotate.isHidden = false
|
|
|
self.buttonAddParticipant.isHidden = false
|
|
|
self.buttonSpeaker.isHidden = false
|
|
|
self.buttonWB.isHidden = false
|
|
@@ -450,16 +501,25 @@ class QmeraVideoViewController: UIViewController {
|
|
|
if(wbRoomId.isEmpty){
|
|
|
let me = UserDefaults.standard.string(forKey: "me")!
|
|
|
let tid = CoreMessage_TMessageUtil.getTID()
|
|
|
- wbRoomId = "\(me)\(tid)"
|
|
|
+ wbRoomId = "\(me)wbvc\(tid)"
|
|
|
wbVC!.roomId = wbRoomId
|
|
|
var destinations = [String]()
|
|
|
+ var destString = ""
|
|
|
for d in dataPerson{
|
|
|
- destinations.append(d["deviceId"]!!)
|
|
|
+ destinations.append(d["f_pin"]!!)
|
|
|
+ if destString.isEmpty{
|
|
|
+ destString = d["f_pin"]!!
|
|
|
+ } else {
|
|
|
+ destString = destString + ",\(d["f_pin"]!!)"
|
|
|
+ }
|
|
|
}
|
|
|
wbVC!.destinations = destinations
|
|
|
wbVC!.sendInit()
|
|
|
+ UserDefaults.standard.set("\(me),\(destString)", forKey: "wb_vc")
|
|
|
}
|
|
|
else {
|
|
|
+ self.wbTimer.invalidate()
|
|
|
+ self.buttonWB.backgroundColor = .lightGray
|
|
|
wbVC!.roomId = wbRoomId
|
|
|
wbVC!.sendJoin()
|
|
|
}
|
|
@@ -472,16 +532,18 @@ class QmeraVideoViewController: UIViewController {
|
|
|
self.buttonDecline.isHidden = false
|
|
|
self.buttonSpeaker.isHidden = false
|
|
|
self.buttonAddParticipant.isHidden = false
|
|
|
- if(!self.wbRoomId.isEmpty){
|
|
|
- DispatchQueue.main.async {
|
|
|
- self.wbTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.runTimer), userInfo: nil, repeats: true)
|
|
|
- }
|
|
|
- }
|
|
|
+ self.buttonRotate.isHidden = false
|
|
|
+// if(!self.wbRoomId.isEmpty){
|
|
|
+// DispatchQueue.main.async {
|
|
|
+// self.wbTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.runTimer), userInfo: nil, repeats: true)
|
|
|
+// }
|
|
|
+// }
|
|
|
}
|
|
|
}
|
|
|
self.buttonDecline.isHidden = true
|
|
|
self.buttonSpeaker.isHidden = true
|
|
|
self.buttonAddParticipant.isHidden = true
|
|
|
+ self.buttonRotate.isHidden = true
|
|
|
addChild(wbVC!)
|
|
|
wbVC!.view.translatesAutoresizingMaskIntoConstraints = false
|
|
|
view.addSubview(wbVC!.view)
|
|
@@ -513,6 +575,22 @@ class QmeraVideoViewController: UIViewController {
|
|
|
self.stackViewToolbar.alignment = .center
|
|
|
self.stackViewToolbar.spacing = 30
|
|
|
|
|
|
+ self.view.addSubview(buttonRotate)
|
|
|
+ buttonRotate.translatesAutoresizingMaskIntoConstraints = false
|
|
|
+ buttonRotate.frame.size = CGSize(width: 70.0, height: 70.0)
|
|
|
+ NSLayoutConstraint.activate([
|
|
|
+ buttonRotate.widthAnchor.constraint(equalToConstant: 70.0),
|
|
|
+ buttonRotate.heightAnchor.constraint(equalToConstant: 70.0),
|
|
|
+ buttonRotate.centerXAnchor.constraint(equalTo: self.view.centerXAnchor),
|
|
|
+ buttonRotate.bottomAnchor.constraint(equalTo: self.stackViewToolbar.topAnchor, constant: -10.0)
|
|
|
+ ])
|
|
|
+ buttonRotate.backgroundColor = .secondaryColor
|
|
|
+ buttonRotate.setImage(UIImage(systemName: "arrow.triangle.2.circlepath.camera", withConfiguration: UIImage.SymbolConfiguration(pointSize: 30, weight: .medium, scale: .default)), for: .normal)
|
|
|
+ buttonRotate.tintColor = .mainColor
|
|
|
+ buttonRotate.circle()
|
|
|
+ buttonRotate.isHidden = true
|
|
|
+ buttonRotate.addTarget(self, action: #selector(camera(sender:)), for: .touchUpInside)
|
|
|
+
|
|
|
view.addSubview(buttonAddParticipant)
|
|
|
buttonAddParticipant.translatesAutoresizingMaskIntoConstraints = false
|
|
|
buttonAddParticipant.frame.size = CGSize(width: 70.0, height: 70.0)
|
|
@@ -534,9 +612,9 @@ class QmeraVideoViewController: UIViewController {
|
|
|
buttonSpeaker.widthAnchor.constraint(equalToConstant: 70.0),
|
|
|
buttonSpeaker.heightAnchor.constraint(equalToConstant: 70.0)
|
|
|
])
|
|
|
- buttonSpeaker.backgroundColor = .secondaryColor
|
|
|
buttonSpeaker.setImage(UIImage(systemName: "speaker.wave.2", withConfiguration: UIImage.SymbolConfiguration(pointSize: 30, weight: .medium, scale: .default)), for: .normal)
|
|
|
- buttonSpeaker.tintColor = .mainColor
|
|
|
+ self.buttonSpeaker.backgroundColor = .lightGray
|
|
|
+ self.buttonSpeaker.tintColor = .mainColor
|
|
|
buttonSpeaker.circle()
|
|
|
buttonSpeaker.isHidden = true
|
|
|
buttonSpeaker.addTarget(self, action: #selector(didTapSpeakerButton(sender:)), for: .touchUpInside)
|
|
@@ -652,13 +730,7 @@ class QmeraVideoViewController: UIViewController {
|
|
|
}
|
|
|
self.isSpeaker = isSpeaker
|
|
|
}
|
|
|
-// do {
|
|
|
-// try AVAudioSession.sharedInstance().setCategory(isSpeaker ? .playAndRecord : .playAndRecord, options: isSpeaker ? .defaultToSpeaker : .duckOthers)
|
|
|
-// try AVAudioSession.sharedInstance().setMode(isSpeaker ? .videoChat : .videoChat)
|
|
|
-// try AVAudioSession.sharedInstance().overrideOutputAudioPort(isSpeaker ? .speaker : .none)
|
|
|
-// } catch {
|
|
|
-//
|
|
|
-// }
|
|
|
+ Nexilis.turnSpeakerOn(bSpeakerOn: isSpeaker)
|
|
|
}
|
|
|
|
|
|
@objc func didTapSpeakerButton(sender: AnyObject){
|
|
@@ -689,17 +761,29 @@ class QmeraVideoViewController: UIViewController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ @objc func camera(sender: Any?) {
|
|
|
+ if frontCamera {
|
|
|
+ API.changeCameraParam(nCameraIdx: 0, nResolutionIndex: 2, nQuality: 4)
|
|
|
+ frontCamera = false
|
|
|
+ } else {
|
|
|
+ API.changeCameraParam(nCameraIdx: 1, nResolutionIndex: 2, nQuality: 4)
|
|
|
+ frontCamera = true
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
@objc func hideToolbar() {
|
|
|
DispatchQueue.main.async {
|
|
|
if self.showStackViewToolbar {
|
|
|
self.showStackViewToolbar = false
|
|
|
- self.constraintBottomStackViewToolbar.constant = 70
|
|
|
+ self.constraintBottomStackViewToolbar.constant = 150
|
|
|
+ self.constraintLeftStackViewToolbar2.constant = -60
|
|
|
UIView.animate(withDuration: 0.35, animations: {
|
|
|
self.view.layoutIfNeeded()
|
|
|
})
|
|
|
} else {
|
|
|
self.showStackViewToolbar = true
|
|
|
self.constraintBottomStackViewToolbar.constant = -60
|
|
|
+ self.constraintLeftStackViewToolbar2.constant = 10
|
|
|
UIView.animate(withDuration: 0.35, animations: {
|
|
|
self.view.layoutIfNeeded()
|
|
|
})
|
|
@@ -713,14 +797,7 @@ class QmeraVideoViewController: UIViewController {
|
|
|
let message = (data?["message"] ?? "") as! String
|
|
|
var remoteChannel = [String:String]()
|
|
|
let arrayMessage = message.split(separator: ",")
|
|
|
- if state == 0 {
|
|
|
- if !isInisiator && self.dataPerson.count == 1 {
|
|
|
- DispatchQueue.main.async {
|
|
|
- self.setSpeaker(isSpeaker: true)
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- else if(state == 35){
|
|
|
+ if(state == 35){
|
|
|
DispatchQueue.main.async {
|
|
|
if self.dataPerson.count > 1 {
|
|
|
if !self.transformZoomAfterNewUserMore2 {
|
|
@@ -771,9 +848,9 @@ class QmeraVideoViewController: UIViewController {
|
|
|
self.listRemoteViewFix[1].transform = CGAffineTransform.init(scaleX: 1.4, y: 1.3).rotated(by: (CGFloat.pi * 3 )/2)
|
|
|
}
|
|
|
}
|
|
|
- let pictureImage = self.dataPerson[i]["picture"]!
|
|
|
- let namePerson = self.dataPerson[i]["name"]!
|
|
|
- if (pictureImage != "" && pictureImage != nil) {
|
|
|
+ let pictureImage = self.dataPerson[i]["picture"] ?? ""
|
|
|
+ let namePerson = self.dataPerson[i]["name"] ?? ""
|
|
|
+ if (!pictureImage!.isEmpty) {
|
|
|
self.listRemoteViewFix[i].setImage(name: pictureImage!)
|
|
|
self.listRemoteViewFix[i].contentMode = .scaleAspectFill
|
|
|
} else {
|
|
@@ -808,9 +885,9 @@ class QmeraVideoViewController: UIViewController {
|
|
|
} else {
|
|
|
self.listRemoteViewFix[i].transform = CGAffineTransform.init(scaleX: 1.4, y: 1.3).rotated(by: (CGFloat.pi * 3 )/2)
|
|
|
}
|
|
|
- let pictureImage = self.dataPerson[self.dataPerson.count - 1]["picture"]!
|
|
|
- let namePerson = self.dataPerson[self.dataPerson.count - 1]["name"]!
|
|
|
- if (pictureImage != "" && pictureImage != nil) {
|
|
|
+ let pictureImage = self.dataPerson[self.dataPerson.count - 1]["picture"] ?? ""
|
|
|
+ let namePerson = self.dataPerson[self.dataPerson.count - 1]["name"] ?? ""
|
|
|
+ if (!pictureImage!.isEmpty) {
|
|
|
self.listRemoteViewFix[i].setImage(name: pictureImage!)
|
|
|
self.listRemoteViewFix[i].contentMode = .scaleAspectFill
|
|
|
} else {
|
|
@@ -852,7 +929,6 @@ class QmeraVideoViewController: UIViewController {
|
|
|
DispatchQueue.main.async {
|
|
|
if self.isInisiator && self.name.isDescendant(of: self.view) {
|
|
|
self.didTapAcceptCallButton()
|
|
|
- self.setSpeaker(isSpeaker: true)
|
|
|
}
|
|
|
let indexPerson = self.dataPerson.firstIndex(where: {$0["f_pin"]!! == arrayMessage[1]})
|
|
|
if indexPerson != nil {
|
|
@@ -888,6 +964,9 @@ class QmeraVideoViewController: UIViewController {
|
|
|
if self.buttonAccept.isDescendant(of: self.view) {
|
|
|
self.buttonAccept.removeFromSuperview()
|
|
|
}
|
|
|
+ if self.buttonRotate.isDescendant(of: self.view) {
|
|
|
+ self.buttonRotate.removeFromSuperview()
|
|
|
+ }
|
|
|
if self.wbVC != nil{
|
|
|
self.wbVC!.close?()
|
|
|
}
|
|
@@ -921,6 +1000,9 @@ class QmeraVideoViewController: UIViewController {
|
|
|
if self.buttonAccept.isDescendant(of: self.view) {
|
|
|
self.buttonAccept.removeFromSuperview()
|
|
|
}
|
|
|
+ if self.buttonRotate.isDescendant(of: self.view) {
|
|
|
+ self.buttonRotate.removeFromSuperview()
|
|
|
+ }
|
|
|
if self.wbVC != nil{
|
|
|
self.wbVC!.close?()
|
|
|
}
|
|
@@ -1105,9 +1187,9 @@ class QmeraVideoViewController: UIViewController {
|
|
|
self.containerLabelName[i].frame = CGRect(x: 0, y: 170 * i, width: 120, height: 30)
|
|
|
self.containerLabelName[i].backgroundColor = .orangeBNI.withAlphaComponent(0.5)
|
|
|
self.containerLabelName[i].makeRoundedView(radius: 8.0)
|
|
|
- let pictureImage = self.dataPerson[i]["picture"]!
|
|
|
- let namePerson = self.dataPerson[i]["name"]!
|
|
|
- if (pictureImage != "" && pictureImage != nil) {
|
|
|
+ let pictureImage = self.dataPerson[i]["picture"] ?? ""
|
|
|
+ let namePerson = self.dataPerson[i]["name"] ?? ""
|
|
|
+ if (!pictureImage!.isEmpty) {
|
|
|
self.listRemoteViewFix[i].setImage(name: pictureImage!)
|
|
|
self.listRemoteViewFix[i].contentMode = .scaleAspectFill
|
|
|
} else {
|
|
@@ -1133,9 +1215,9 @@ class QmeraVideoViewController: UIViewController {
|
|
|
self.containerLabelName[i].frame = CGRect(x: 0, y: 170 * i, width: 120, height: 30)
|
|
|
self.containerLabelName[i].backgroundColor = .orangeBNI.withAlphaComponent(0.5)
|
|
|
self.containerLabelName[i].makeRoundedView(radius: 8.0)
|
|
|
- let pictureImage = self.dataPerson[self.dataPerson.count - 1]["picture"]!
|
|
|
- let namePerson = self.dataPerson[self.dataPerson.count - 1]["name"]!
|
|
|
- if (pictureImage != "" && pictureImage != nil) {
|
|
|
+ let pictureImage = self.dataPerson[self.dataPerson.count - 1]["picture"] ?? ""
|
|
|
+ let namePerson = self.dataPerson[self.dataPerson.count - 1]["name"] ?? ""
|
|
|
+ if (!pictureImage!.isEmpty) {
|
|
|
self.listRemoteViewFix[i].setImage(name: pictureImage!)
|
|
|
self.listRemoteViewFix[i].contentMode = .scaleAspectFill
|
|
|
} else {
|
|
@@ -1167,6 +1249,23 @@ extension QmeraVideoViewController : WhiteboardReceiver {
|
|
|
DispatchQueue.main.async {
|
|
|
self.wbTimer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(self.runTimer), userInfo: nil, repeats: true)
|
|
|
}
|
|
|
+ let me = UserDefaults.standard.string(forKey: "me")!
|
|
|
+ var destString = ""
|
|
|
+ for d in dataPerson{
|
|
|
+ if d["f_pin"]!! == roomId.components(separatedBy: "wbvc")[0] {
|
|
|
+ continue
|
|
|
+ }
|
|
|
+ if destString.isEmpty{
|
|
|
+ destString = d["f_pin"]!!
|
|
|
+ } else {
|
|
|
+ destString = destString + ",\(d["f_pin"]!!)"
|
|
|
+ }
|
|
|
+ }
|
|
|
+ if destString.isEmpty {
|
|
|
+ UserDefaults.standard.set("\(roomId.components(separatedBy: "wbvc")[0]),\(me)", forKey: "wb_vc")
|
|
|
+ } else {
|
|
|
+ UserDefaults.standard.set("\(roomId.components(separatedBy: "wbvc")[0]),\(me),\(destString)", forKey: "wb_vc")
|
|
|
+ }
|
|
|
wbRoomId = roomId
|
|
|
}
|
|
|
}
|