WhiteboardViewController.swift 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365
  1. //
  2. // WhiteboardViewController.swift
  3. // NexilisLite
  4. //
  5. // Created by Kevin Maulana on 31/03/22.
  6. //
  7. // Rn
  8. // onalphachanged
  9. import UIKit
  10. class WhiteboardViewController: UIViewController, WhiteboardDelegate {
  11. func draw(x: String, y: String, w: String, h: String, fc: String, sw: String, xo: String, yo: String, data: String) {
  12. wb!.draw(x: x, y: y, w: w, h: h, fc: fc, sw: sw, xo: xo, yo: yo, data: data)
  13. }
  14. @objc func clear(){
  15. wb?.clear()
  16. }
  17. var wbc : WhiteboardCanvas?
  18. var wbcConstraintTop = NSLayoutConstraint()
  19. var wbcConstraintBottom = NSLayoutConstraint()
  20. var wbcConstraintLeft = NSLayoutConstraint()
  21. var wbcConstraintRight = NSLayoutConstraint()
  22. var wb : Whiteboard?
  23. var roomId = ""
  24. var destinations = [String]()
  25. var incoming = false
  26. var fromContact: Int?
  27. let myImage = UIImageView()
  28. let name = UILabel()
  29. let profileImage = UIImageView()
  30. let labelIncomingOutgoing = UILabel()
  31. var user: User?
  32. let buttonDecline = UIButton()
  33. let buttonAccept = UIButton()
  34. var constraintLeadingButtonDecline = NSLayoutConstraint()
  35. var constraintBottomButtonDecline = NSLayoutConstraint()
  36. required init?(coder: NSCoder) {
  37. super.init(coder: coder)
  38. wb = Whiteboard(delegated: true)
  39. }
  40. override func viewDidLoad() {
  41. super.viewDidLoad()
  42. if fromContact != nil {
  43. addBackgroundIncoming()
  44. addProfileNameCalling()
  45. Calling()
  46. addToolbar()
  47. } else {
  48. initWhiteboard()
  49. }
  50. self.title = "Whiteboard".localized()
  51. let center: NotificationCenter = NotificationCenter.default
  52. center.addObserver(self, selector: #selector(wbSession(notification:)), name: NSNotification.Name(rawValue: "wbSession"), object: nil)
  53. // navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Close".localized(), style: .plain, target: self, action: #selector(close))
  54. // navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Clear".localized(), style: .plain,target: self, action: #selector(clear))
  55. // Do any additional setup after loading the view.
  56. }
  57. func addBackgroundIncoming() {
  58. view.addSubview(myImage)
  59. myImage.translatesAutoresizingMaskIntoConstraints = false
  60. NSLayoutConstraint.activate([
  61. myImage.topAnchor.constraint(equalTo: view.topAnchor),
  62. myImage.bottomAnchor.constraint(equalTo: view.bottomAnchor),
  63. myImage.leadingAnchor.constraint(equalTo: view.leadingAnchor),
  64. myImage.trailingAnchor.constraint(equalTo: view.trailingAnchor),
  65. ])
  66. myImage.backgroundColor = .lightGray
  67. myImage.tintColor = .secondaryColor
  68. let image = user!.thumb
  69. if image.isEmpty {
  70. myImage.image = UIImage(systemName: "person")
  71. myImage.contentMode = .scaleAspectFit
  72. } else {
  73. myImage.setImage(name: image)
  74. myImage.contentMode = .scaleAspectFill
  75. }
  76. }
  77. func addProfileNameCalling() {
  78. view.addSubview(profileImage)
  79. profileImage.translatesAutoresizingMaskIntoConstraints = false
  80. profileImage.frame.size = CGSize(width: 60.0, height: 60.0)
  81. NSLayoutConstraint.activate([
  82. profileImage.topAnchor.constraint(equalTo: view.topAnchor, constant: 40.0),
  83. profileImage.centerXAnchor.constraint(equalTo: view.centerXAnchor),
  84. profileImage.widthAnchor.constraint(equalToConstant: 60.0),
  85. profileImage.heightAnchor.constraint(equalToConstant: 63.0)
  86. ])
  87. profileImage.backgroundColor = .lightGray
  88. profileImage.tintColor = .secondaryColor
  89. profileImage.circle()
  90. let image = user!.thumb
  91. if image.isEmpty {
  92. profileImage.image = UIImage(systemName: "person")
  93. profileImage.contentMode = .scaleAspectFit
  94. profileImage.layer.borderWidth = 1
  95. profileImage.layer.borderColor = UIColor.secondaryColor.cgColor
  96. } else {
  97. profileImage.setImage(name: image)
  98. profileImage.contentMode = .scaleAspectFill
  99. }
  100. view.addSubview(name)
  101. name.translatesAutoresizingMaskIntoConstraints = false
  102. NSLayoutConstraint.activate([
  103. name.topAnchor.constraint(equalTo: profileImage.bottomAnchor, constant: 5.0),
  104. name.centerXAnchor.constraint(equalTo: view.centerXAnchor)
  105. ])
  106. name.font = UIFont.systemFont(ofSize: 12)
  107. name.backgroundColor = .black.withAlphaComponent(0.05)
  108. name.layer.cornerRadius = 5.0
  109. name.clipsToBounds = true
  110. name.textColor = .mainColor
  111. name.text = user?.fullName.trimmingCharacters(in: .whitespaces)
  112. }
  113. func Calling() {
  114. view.addSubview(labelIncomingOutgoing)
  115. labelIncomingOutgoing.translatesAutoresizingMaskIntoConstraints = false
  116. NSLayoutConstraint.activate([
  117. labelIncomingOutgoing.topAnchor.constraint(equalTo: name.bottomAnchor, constant: 40.0),
  118. labelIncomingOutgoing.centerXAnchor.constraint(equalTo: view.centerXAnchor)
  119. ])
  120. if fromContact == 0 {
  121. labelIncomingOutgoing.text = "Waiting for answer".localized() + "..."
  122. _ = DigiX.write(message: CoreMessage_TMessageBank.wbCreate(l_pin: user!.pin))
  123. } else {
  124. labelIncomingOutgoing.text = "Incoming Whiteboard".localized() + "..."
  125. }
  126. labelIncomingOutgoing.font = UIFont.systemFont(ofSize: 12)
  127. labelIncomingOutgoing.backgroundColor = .black.withAlphaComponent(0.05)
  128. labelIncomingOutgoing.layer.cornerRadius = 5.0
  129. labelIncomingOutgoing.clipsToBounds = true
  130. labelIncomingOutgoing.textColor = .mainColor
  131. }
  132. func addToolbar() {
  133. view.addSubview(buttonDecline)
  134. buttonDecline.translatesAutoresizingMaskIntoConstraints = false
  135. buttonDecline.frame.size = CGSize(width: 70.0, height: 70.0)
  136. if fromContact == 0 {
  137. constraintLeadingButtonDecline = buttonDecline.centerXAnchor.constraint(equalTo: view.centerXAnchor)
  138. } else {
  139. constraintLeadingButtonDecline = buttonDecline.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: view.frame.width * 0.2)
  140. }
  141. constraintBottomButtonDecline = buttonDecline.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -60.0)
  142. NSLayoutConstraint.activate([
  143. constraintBottomButtonDecline,
  144. constraintLeadingButtonDecline,
  145. buttonDecline.widthAnchor.constraint(equalToConstant: 70.0),
  146. buttonDecline.heightAnchor.constraint(equalToConstant: 70.0)
  147. ])
  148. buttonDecline.backgroundColor = .red
  149. buttonDecline.circle()
  150. buttonDecline.setImage(UIImage(systemName: "xmark", withConfiguration: UIImage.SymbolConfiguration(pointSize: 30, weight: .medium, scale: .default)), for: .normal)
  151. buttonDecline.tintColor = .white
  152. buttonDecline.addTarget(self, action: #selector(didTapDeclineCallButton(sender:)), for: .touchUpInside)
  153. if fromContact == 1 {
  154. view.addSubview(buttonAccept)
  155. buttonAccept.translatesAutoresizingMaskIntoConstraints = false
  156. buttonAccept.frame.size = CGSize(width: 70.0, height: 70.0)
  157. NSLayoutConstraint.activate([
  158. buttonAccept.bottomAnchor.constraint(equalTo: view.bottomAnchor, constant: -60.0),
  159. buttonAccept.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -(view.frame.width * 0.2)),
  160. buttonAccept.widthAnchor.constraint(equalToConstant: 70.0),
  161. buttonAccept.heightAnchor.constraint(equalToConstant: 70.0)
  162. ])
  163. buttonAccept.backgroundColor = .greenColor
  164. buttonAccept.circle()
  165. buttonAccept.setImage(UIImage(systemName: "checkmark", withConfiguration: UIImage.SymbolConfiguration(pointSize: 30, weight: .medium, scale: .default)), for: .normal)
  166. buttonAccept.tintColor = .white
  167. buttonAccept.addTarget(self, action: #selector(didTapAcceptCallButton), for: .touchUpInside)
  168. }
  169. }
  170. @objc func didTapDeclineCallButton(sender: Any) {
  171. let alert = LibAlertController(title: "End Whiteboard Session".localized(), message: "Are you sure you want to end whiteboard session?".localized(), preferredStyle: .alert)
  172. alert.addAction(UIAlertAction(title: "No".localized(), style: UIAlertAction.Style.default, handler: nil))
  173. alert.addAction(UIAlertAction(title: "Yes".localized(), style: UIAlertAction.Style.default, handler: {(_) in
  174. if self.fromContact == 0 {
  175. _ = DigiX.write(message: CoreMessage_TMessageBank.wbEnded(l_pin: self.user!.pin))
  176. } else {
  177. _ = DigiX.write(message: CoreMessage_TMessageBank.wbReject(l_pin: self.user!.pin))
  178. }
  179. self.dismiss(animated: true, completion: nil)
  180. }))
  181. self.present(alert, animated: true, completion: nil)
  182. }
  183. @objc func didTapAcceptCallButton() {
  184. _ = DigiX.write(message: CoreMessage_TMessageBank.wbAccept(l_pin: user!.pin))
  185. self.myImage.removeFromSuperview()
  186. self.name.removeFromSuperview()
  187. self.profileImage.removeFromSuperview()
  188. self.labelIncomingOutgoing.removeFromSuperview()
  189. self.buttonDecline.removeFromSuperview()
  190. self.buttonAccept.removeFromSuperview()
  191. NSLayoutConstraint.deactivate([
  192. self.constraintLeadingButtonDecline,
  193. self.constraintBottomButtonDecline
  194. ])
  195. self.initWhiteboard()
  196. UserDefaults.standard.set("\(user!.pin),\(User.getMyPin() ?? "")", forKey: "wb_vc")
  197. }
  198. @objc func wbSession(notification: NSNotification) {
  199. DispatchQueue.main.async { [self] in
  200. let data:[AnyHashable : Any] = notification.userInfo!
  201. if let message = data["message"] as? TMessage {
  202. let status = message.getBody(key: CoreMessage_TMessageKey.STATUS, default_value: "")
  203. switch (Int(status)) {
  204. case CoreMessage_TMessageCode.WB_ACCEPT_INCOMING:
  205. ////print(("WB_ACCEPT_INCOMING")
  206. let f_pin = message.getBody(key: CoreMessage_TMessageKey.F_USER_ID, default_value: "")
  207. _ = DigiX.write(message: CoreMessage_TMessageBank.wbOffhook(l_pin: f_pin))
  208. DispatchQueue.main.async {
  209. self.myImage.removeFromSuperview()
  210. self.name.removeFromSuperview()
  211. self.profileImage.removeFromSuperview()
  212. self.labelIncomingOutgoing.removeFromSuperview()
  213. self.buttonDecline.removeFromSuperview()
  214. NSLayoutConstraint.deactivate([
  215. self.constraintLeadingButtonDecline,
  216. self.constraintBottomButtonDecline
  217. ])
  218. self.initWhiteboard()
  219. let tid = CoreMessage_TMessageUtil.getTID()
  220. self.roomId = "\(f_pin)WB\(tid)"
  221. self.destinations = [f_pin]
  222. self.sendInit()
  223. UserDefaults.standard.set("\(User.getMyPin() ?? ""),\(f_pin)", forKey: "wb_vc")
  224. }
  225. case CoreMessage_TMessageCode.WB_REJECT_INCOMING,CoreMessage_TMessageCode.WB_END:
  226. ////print(("WB_REJECT_INCOMING \(status)")
  227. if self.labelIncomingOutgoing.isDescendant(of: self.view) {
  228. self.labelIncomingOutgoing.text = "WhiteBoard session is over".localized()
  229. }
  230. if !self.labelIncomingOutgoing.isDescendant(of: self.view) {
  231. let conainerEnd = UIView()
  232. view.addSubview(conainerEnd)
  233. conainerEnd.anchor(top: view.topAnchor, left: view.leftAnchor, bottom: view.bottomAnchor, right: view.rightAnchor)
  234. conainerEnd.backgroundColor = .white
  235. let labelEnd = UILabel()
  236. conainerEnd.addSubview(labelEnd)
  237. labelEnd.anchor(centerX: conainerEnd.centerXAnchor, centerY: conainerEnd.centerYAnchor)
  238. labelEnd.font = .systemFont(ofSize: 25)
  239. labelEnd.textColor = .mainColor
  240. labelEnd.text = "WhiteBoard session is over".localized()
  241. }
  242. if self.buttonDecline.isDescendant(of: self.view) {
  243. self.buttonDecline.removeFromSuperview()
  244. }
  245. if self.buttonAccept.isDescendant(of: self.view) {
  246. self.buttonAccept.removeFromSuperview()
  247. }
  248. DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
  249. self.dismiss(animated: true, completion: nil)
  250. }
  251. case CoreMessage_TMessageCode.WB_OFFHOOK:
  252. ////print(("WB_OFFHOOK")
  253. break
  254. case CoreMessage_TMessageCode.WB_RINGING:
  255. ////print(("WB_RINGING")
  256. break
  257. default:
  258. ////print(("default")
  259. break
  260. }
  261. }
  262. }
  263. }
  264. func initWhiteboard(){
  265. _ = self.view.frame.width * 20.0 / 9.0
  266. let rect = CGRect(x: 0.0, y: 0.0, width: self.view.frame.width, height: self.view.frame.height)
  267. wbc = WhiteboardCanvas(frame: rect)
  268. // wbc?.translatesAutoresizingMaskIntoConstraints = false
  269. // wbcConstraintTop = (wbc?.topAnchor.constraint(equalTo: self.view.topAnchor))!
  270. // wbcConstraintBottom = (wbc?.bottomAnchor.constraint(equalTo: self.view.bottomAnchor))!
  271. // wbcConstraintRight = (wbc?.rightAnchor.constraint(equalTo: self.view.rightAnchor))!
  272. // wbcConstraintLeft = (wbc?.leftAnchor.constraint(equalTo: self.view.leftAnchor))!
  273. // NSLayoutConstraint.activate([wbcConstraintTop, wbcConstraintBottom, wbcConstraintLeft, wbcConstraintRight])
  274. wb?.canvas = wbc
  275. self.view.addSubview(wbc!)
  276. DigiX.setWhiteboardDelegate(delegate: self)
  277. }
  278. func sendInit(){
  279. let d = destinations.joined(separator: ",")
  280. ////print(("KOCAK \(d)")
  281. // roomId = "\(me)\(tid)"
  282. wb?.setRoomId(roomId: roomId)
  283. wb!.sendInit(destinations: d)
  284. }
  285. func sendJoin(){
  286. wb?.setRoomId(roomId: roomId)
  287. wb!.sendJoin()
  288. }
  289. var close : (() -> Void)?
  290. func terminate(){
  291. wb?.sendTerminate()
  292. DigiX.setWhiteboardDelegate(delegate: nil)
  293. close?()
  294. }
  295. @IBAction func didTapClose(_ sender: Any) {
  296. if fromContact != nil {
  297. didTapDeclineCallButton(sender: 0)
  298. return
  299. }
  300. close?()
  301. }
  302. @IBAction func didTapClear(_ sender: Any) {
  303. wb?.clear()
  304. wb?.sendClear()
  305. }
  306. @IBAction func onAlphaChanged(_ sender: UISlider) {
  307. let alp = sender.value / 100.0
  308. view.backgroundColor = UIColor(red: 1.0, green: 1.0, blue: 1.0, alpha: CGFloat(alp))
  309. }
  310. /*
  311. // MARK: - Navigation
  312. // In a storyboard-based application, you will often want to do a little preparation before navigation
  313. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  314. // Get the new view controller using segue.destination.
  315. // Pass the selected object to the new view controller.
  316. }
  317. */
  318. }
  319. extension WhiteboardViewController : WhiteboardReceiver {
  320. func incomingWB(roomId: String) {
  321. self.roomId = roomId
  322. self.sendJoin()
  323. }
  324. func cancel(roomId: String) {
  325. }
  326. }