|
@@ -28,6 +28,16 @@ class SeminarViewController: UIViewController {
|
|
|
|
|
|
private var hasRaiseHand = false
|
|
|
|
|
|
+ private var mIsSwitch = false
|
|
|
+
|
|
|
+ private var currentSpeakingBC = "-666"
|
|
|
+
|
|
|
+ private var currentSpeakingVW = "-666"
|
|
|
+
|
|
|
+ private var secondViewHeight = 0.0
|
|
|
+
|
|
|
+ private var secondViewWidth = 0.0
|
|
|
+
|
|
|
private var heightTableView: NSLayoutConstraint?
|
|
|
|
|
|
var wbVC : WhiteboardViewController?
|
|
@@ -64,6 +74,8 @@ class SeminarViewController: UIViewController {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ var statusView = UIView()
|
|
|
+
|
|
|
lazy var status: UILabel = {
|
|
|
let label = UILabel()
|
|
|
label.font = UIFont.systemFont(ofSize: 14)
|
|
@@ -97,6 +109,11 @@ class SeminarViewController: UIViewController {
|
|
|
return imageView
|
|
|
}()
|
|
|
|
|
|
+ var tvBRotation = 0.0
|
|
|
+ var tvSRotation = 0.0
|
|
|
+ var ivSRotation = 0.0
|
|
|
+ var ivMRotation = 0.0
|
|
|
+
|
|
|
lazy var tableView: UITableView = {
|
|
|
let tableView = UITableView()
|
|
|
tableView.dataSource = self
|
|
@@ -123,16 +140,6 @@ class SeminarViewController: UIViewController {
|
|
|
return textView
|
|
|
}()
|
|
|
|
|
|
-// lazy var like: UIButton = {
|
|
|
-// let button = UIButton()
|
|
|
-// button.setImage(UIImage(systemName: "heart")?.withTintColor(.white, renderingMode: .alwaysOriginal), for: .normal)
|
|
|
-// button.imageView?.contentMode = .scaleAspectFit
|
|
|
-// button.contentVerticalAlignment = .fill
|
|
|
-// button.contentHorizontalAlignment = .fill
|
|
|
-// button.addTarget(self, action: #selector(liked(sender:)), for: .touchUpInside)
|
|
|
-// return button
|
|
|
-// }()
|
|
|
-//
|
|
|
lazy var send: UIButton = {
|
|
|
let button = UIButton()
|
|
|
button.setImage(UIImage(named: "Send-(White)", in: Bundle.resourceBundle(for: Nexilis.self), with: nil), for: .normal)
|
|
@@ -233,6 +240,14 @@ class SeminarViewController: UIViewController {
|
|
|
|
|
|
navigationController?.changeAppearance(clear: true)
|
|
|
|
|
|
+ let screenBounds = UIScreen.main.bounds
|
|
|
+
|
|
|
+ let screenWidth = screenBounds.width
|
|
|
+ let screenHeight = screenBounds.height
|
|
|
+
|
|
|
+ secondViewWidth = screenWidth / 3.0
|
|
|
+ secondViewHeight = screenHeight / 3.0
|
|
|
+
|
|
|
let buttonBack = UIButton()
|
|
|
buttonBack.frame = CGRect(x:0, y:0, width:30, height:30)
|
|
|
buttonBack.setImage(UIImage(systemName: "chevron.backward")?.withTintColor(.mainColor, renderingMode: .alwaysOriginal), for: .normal)
|
|
@@ -255,7 +270,6 @@ class SeminarViewController: UIViewController {
|
|
|
view.addSubview(ivRemoteViewS)
|
|
|
ivRemoteViewM.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor)
|
|
|
}
|
|
|
- let statusView = UIView()
|
|
|
view.addSubview(statusView)
|
|
|
statusView.backgroundColor = .white.withAlphaComponent(0.2)
|
|
|
statusView.layer.cornerRadius = 8.0
|
|
@@ -333,7 +347,7 @@ class SeminarViewController: UIViewController {
|
|
|
])
|
|
|
}
|
|
|
|
|
|
- func switchRaiseHand(){
|
|
|
+ func switchRaiseHand(raiseHand: Bool){
|
|
|
if hasRaiseHand {
|
|
|
raiseHandBtn.removeFromSuperview()
|
|
|
buttonRotate.widthAnchor.constraint(equalToConstant: 40).isActive = true
|
|
@@ -525,7 +539,74 @@ class SeminarViewController: UIViewController {
|
|
|
}
|
|
|
}
|
|
|
self.navigationController?.present(controller, animated: true, completion: nil)
|
|
|
- // TODO: Show list viewer
|
|
|
+ }
|
|
|
+
|
|
|
+ func switchBroadcaster() {
|
|
|
+ if isLive {
|
|
|
+ if(currentSpeakingBC == "-666") {
|
|
|
+ // toast return
|
|
|
+ return
|
|
|
+ }
|
|
|
+ mIsSwitch = !mIsSwitch
|
|
|
+ if mIsSwitch {
|
|
|
+ adjust(viewOnFront: tvCameraPreviewB, viewOnBack: ivRemoteViewS)
|
|
|
+ } else {
|
|
|
+ adjust(viewOnFront: ivRemoteViewS, viewOnBack: tvCameraPreviewB)
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ if(currentSpeakingVW == "-666") {
|
|
|
+ // toast return
|
|
|
+ return
|
|
|
+ }
|
|
|
+ mIsSwitch = !mIsSwitch
|
|
|
+ let me = UserDefaults.standard.string(forKey: "me")
|
|
|
+ if currentSpeakingVW == me {
|
|
|
+ if mIsSwitch {
|
|
|
+ adjust(viewOnFront: ivRemoteViewM, viewOnBack: tvCameraPreviewS)
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ adjust(viewOnFront: tvCameraPreviewS, viewOnBack: ivRemoteViewM)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ if mIsSwitch {
|
|
|
+ adjust(viewOnFront: ivRemoteViewM, viewOnBack: ivRemoteViewS)
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ adjust(viewOnFront: ivRemoteViewS, viewOnBack: ivRemoteViewM)
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func forceRevertSwitch() {
|
|
|
+ if isLive {
|
|
|
+ adjust(viewOnFront: ivRemoteViewS, viewOnBack: tvCameraPreviewB)
|
|
|
+ mIsSwitch = false
|
|
|
+ } else {
|
|
|
+ let me = UserDefaults.standard.string(forKey: "me")
|
|
|
+ if currentSpeakingVW == me {
|
|
|
+ adjust(viewOnFront: tvCameraPreviewS, viewOnBack: ivRemoteViewS)
|
|
|
+ } else {
|
|
|
+ adjust(viewOnFront: ivRemoteViewS, viewOnBack: ivRemoteViewM)
|
|
|
+ }
|
|
|
+ mIsSwitch = false
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ func adjust(viewOnFront: UIImageView, viewOnBack: UIImageView) {
|
|
|
+ viewOnFront.removeConstraints(viewOnFront.constraints)
|
|
|
+ viewOnBack.removeConstraints(viewOnBack.constraints)
|
|
|
+ viewOnFront.anchor(bottom: view.bottomAnchor, right: view.rightAnchor, paddingBottom: 70.0, width: secondViewWidth, height: secondViewHeight)
|
|
|
+ viewOnBack.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor)
|
|
|
+ btf()
|
|
|
+ view.bringSubviewToFront(viewOnFront)
|
|
|
+ }
|
|
|
+
|
|
|
+ func btf() {
|
|
|
+ view.bringSubviewToFront(stack)
|
|
|
+ view.bringSubviewToFront(statusView)
|
|
|
+ view.bringSubviewToFront(toolbarView)
|
|
|
}
|
|
|
|
|
|
}
|
|
@@ -673,21 +754,137 @@ extension SeminarViewController: SeminarDelegate {
|
|
|
}
|
|
|
}
|
|
|
} else if state == 32 { // initBCA (3* is from Broadcaster PoV)
|
|
|
- // TODO
|
|
|
+ tvCameraPreviewB.removeConstraints(tvCameraPreviewB.constraints)
|
|
|
+ tvCameraPreviewB.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor)
|
|
|
+ view.bringSubviewToFront(tvCameraPreviewB)
|
|
|
+ btf()
|
|
|
} else if state == 33 { // startAudience (3* is from Broadcaster PoV)
|
|
|
+ let m = message.split(separator: ",")
|
|
|
+ let f_pin = m[0]
|
|
|
+ let camera = Int(m[1])
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ let rotation = camera == 1 ? CGFloat.pi * 2.5 : CGFloat.pi * 0.5
|
|
|
+ self.ivRemoteViewS.transform = CGAffineTransform.init(scaleX: 1.9, y: 1.9).rotated(by: rotation)
|
|
|
+ self.ivSRotation = rotation
|
|
|
+ }
|
|
|
+ if currentSpeakingBC != "-666" {
|
|
|
+ viewers.first(where: {$0.f_pin == currentSpeakingBC})?.isRaise = false
|
|
|
+ viewers.first(where: {$0.f_pin == currentSpeakingBC})?.isSpeak = false
|
|
|
+ }
|
|
|
+ if currentSpeakingBC != f_pin {
|
|
|
+ forceRevertSwitch()
|
|
|
+ }
|
|
|
+ viewers.first(where: {$0.f_pin == currentSpeakingBC})?.isRaise = false
|
|
|
+ viewers.first(where: {$0.f_pin == currentSpeakingBC})?.isSpeak = true
|
|
|
+ // TODO: remove badge if no raise hand
|
|
|
|
|
|
} else if state == 34 { // endAudience (3* is from Broadcaster PoV)
|
|
|
-
|
|
|
+ let m = message.split(separator: ",")
|
|
|
+ let f_pin = m[0]
|
|
|
+ if currentSpeakingBC == f_pin {
|
|
|
+ forceRevertSwitch()
|
|
|
+ currentSpeakingBC = "-666"
|
|
|
+ }
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ let rotation = -(self.ivSRotation)
|
|
|
+ self.ivRemoteViewS.transform = CGAffineTransform.init(scaleX: 1.9, y: 1.9).rotated(by: rotation)
|
|
|
+ self.ivSRotation = 0
|
|
|
+ }
|
|
|
+ viewers.first(where: {$0.f_pin == f_pin})?.isRaise = false
|
|
|
+ viewers.first(where: {$0.f_pin == f_pin})?.isSpeak = false
|
|
|
} else if state == 36 || state == 46 { // audience change camera (3* is from Broadcaster PoV)
|
|
|
-
|
|
|
+ let m = message.split(separator: ",")
|
|
|
+ let camera = Int(m[2])
|
|
|
+ let rotation = camera == 1 ? CGFloat.pi * 2.5 : CGFloat.pi * 0.5
|
|
|
+ let scaleY = camera == 1 ? -1.0 : 1.0
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ self.ivRemoteViewS.transform = CGAffineTransform.init(scaleX: 1.9, y: 1.9 * scaleY).rotated(by: rotation - self.ivSRotation)
|
|
|
+ self.ivSRotation = rotation
|
|
|
+ }
|
|
|
} else if state == 42 { // joinBC (4* is from Audience PoV)
|
|
|
-
|
|
|
+ let m = message.split(separator: ",")
|
|
|
+ let camera = Int(m[2])
|
|
|
+ let x = m[5]
|
|
|
+ let camera2 = Int(m[6])
|
|
|
+ let rotation = camera == 1 ? CGFloat.pi * 2.5 : CGFloat.pi * 0.5
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ self.ivRemoteViewM.transform = CGAffineTransform.init(scaleX: 1.9, y: 1.9).rotated(by: rotation - self.ivMRotation)
|
|
|
+ self.ivMRotation = rotation
|
|
|
+ }
|
|
|
+ ivRemoteViewM.removeConstraints(ivRemoteViewM.constraints)
|
|
|
+ ivRemoteViewM.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor)
|
|
|
+ view.bringSubviewToFront(ivRemoteViewM)
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ let rotation = -(self.ivSRotation)
|
|
|
+ self.ivRemoteViewS.transform = CGAffineTransform.init(scaleX: 1.9, y: 1.9).rotated(by: rotation)
|
|
|
+ self.ivSRotation = 0
|
|
|
+ }
|
|
|
+ if x != "NONE" {
|
|
|
+ let rotation2 = camera2 == 1 ? CGFloat.pi * 2.5 : CGFloat.pi * 0.5
|
|
|
+ let scaleY = camera2 == 1 ? -1.0 : 1.0
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ self.ivRemoteViewS.transform = CGAffineTransform.init(scaleX: 1.9, y: 1.9 * scaleY).rotated(by: rotation - self.ivSRotation)
|
|
|
+ self.ivSRotation = rotation
|
|
|
+ }
|
|
|
+ view.bringSubviewToFront(ivRemoteViewS)
|
|
|
+ }
|
|
|
+ btf()
|
|
|
} else if state == 43 { // startAudience (4* is from Audience PoV)
|
|
|
-
|
|
|
+ let m = message.split(separator: ",")
|
|
|
+ let f_pin = String(m[0])
|
|
|
+ tvCameraPreviewS.removeConstraints(tvCameraPreviewS.constraints)
|
|
|
+ tvCameraPreviewS.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor)
|
|
|
+ currentSpeakingVW = f_pin
|
|
|
+ let me = UserDefaults.standard.string(forKey: "me")
|
|
|
+ if currentSpeakingVW == me {
|
|
|
+ hasRaiseHand = false
|
|
|
+ switchRaiseHand(raiseHand: false)
|
|
|
+ }
|
|
|
+ else {
|
|
|
+ switchRaiseHand(raiseHand: true)
|
|
|
+ }
|
|
|
+ // TODO: set whiteboard can draw here
|
|
|
} else if state == 44 { // endAudience (4* is from Audience PoV)
|
|
|
-
|
|
|
+ let m = message.split(separator: ",")
|
|
|
+ let f_pin = String(m[0])
|
|
|
+ let camera = Int(m[1])
|
|
|
+ if f_pin != "NONE" {
|
|
|
+ if mIsSwitch {
|
|
|
+ forceRevertSwitch()
|
|
|
+ }
|
|
|
+ currentSpeakingVW = f_pin
|
|
|
+ let rotation = camera == 1 ? CGFloat.pi * 2.5 : CGFloat.pi * 0.5
|
|
|
+ let scaleY = camera == 1 ? -1.0 : 1.0
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ self.ivRemoteViewS.transform = CGAffineTransform.init(scaleX: 1.9, y: 1.9 * scaleY).rotated(by: rotation - self.ivSRotation)
|
|
|
+ self.ivSRotation = rotation
|
|
|
+ }
|
|
|
+ view.bringSubviewToFront(ivRemoteViewS)
|
|
|
+ } else {
|
|
|
+ if mIsSwitch {
|
|
|
+ forceRevertSwitch()
|
|
|
+ }
|
|
|
+ let me = UserDefaults.standard.string(forKey: "me")
|
|
|
+ if me == f_pin {
|
|
|
+ currentSpeakingVW = "-666"
|
|
|
+ }
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ let rotation = -(self.ivSRotation)
|
|
|
+ self.ivRemoteViewS.transform = CGAffineTransform.init(scaleX: 1.9, y: 1.9).rotated(by: rotation)
|
|
|
+ self.ivSRotation = 0
|
|
|
+ }
|
|
|
+ hasRaiseHand = false
|
|
|
+ switchRaiseHand(raiseHand: true)
|
|
|
+ // TODO: set whiteboard can draw here
|
|
|
+ }
|
|
|
} else if state == 45 { // CCPb Br.ID Br.Title Br.CameraID Br.OS : (4* is from Audience PoV) broadcaster change camera
|
|
|
-
|
|
|
+ let m = message.split(separator: ",")
|
|
|
+ let camera = Int(m[2])
|
|
|
+ let rotation = camera == 1 ? CGFloat.pi * 2.5 : CGFloat.pi * 0.5
|
|
|
+ DispatchQueue.main.async {
|
|
|
+ self.ivRemoteViewM.transform = CGAffineTransform.init(scaleX: 1.9, y: 1.9).rotated(by: rotation - self.ivMRotation)
|
|
|
+ self.ivMRotation = rotation
|
|
|
+ }
|
|
|
} else if state == 88 {
|
|
|
DispatchQueue.main.async {
|
|
|
self.status.text = "Seminar ended".localized()
|
|
@@ -721,8 +918,6 @@ extension SeminarViewController: SeminarDelegate {
|
|
|
// TODO: edit badges
|
|
|
}
|
|
|
}
|
|
|
- // wat to do
|
|
|
-
|
|
|
} else if state == 97 { // someone left
|
|
|
let m = message.split(separator: ",", omittingEmptySubsequences: false)
|
|
|
let name = m[3].trimmingCharacters(in: .whitespaces)
|