ContactCallViewController.swift 22 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417
  1. //
  2. // ContactViewController.swift
  3. // FloatingButtonApp
  4. //
  5. // Created by Yayan Dwi on 05/08/21.
  6. //
  7. import UIKit
  8. import nuSDKService
  9. import NotificationBannerSwift
  10. class ContactCallViewController: UIViewController {
  11. @IBOutlet weak var tableView: UITableView!
  12. var dataPersonNotChange: [[String: String?]] = []
  13. var dataPerson: [[String: String?]] = []
  14. var fillteredData: [[String: String?]] = []
  15. var isAddParticipantVideo: Bool = false
  16. var connectedCall: [[String: String?]] = []
  17. var isDismiss: (([String: String?]) -> ())?
  18. var searchController: UISearchController!
  19. var isSearchBarEmpty: Bool {
  20. return searchController.searchBar.text!.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
  21. }
  22. var isFilltering: Bool {
  23. return searchController.isActive && !isSearchBarEmpty
  24. }
  25. var onlyAudioOrVideo = 0
  26. var startWhiteBoard = false
  27. var startSS = false
  28. override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
  29. if (segue.identifier == "videoVC") {
  30. if !CheckConnection.isConnectedToNetwork() {
  31. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  32. imageView.tintColor = .white
  33. let banner = FloatingNotificationBanner(title: "Check your connection".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)
  34. banner.show()
  35. return
  36. }
  37. let destination = segue.destination as! QmeraVideoViewController
  38. let index = sender as! UIButton
  39. destination.dataPerson.append(dataPerson[index.tag])
  40. }
  41. }
  42. override func viewDidDisappear(_ animated: Bool) {
  43. NotificationCenter.default.removeObserver(self)
  44. NotificationCenter.default.post(name: NSNotification.Name(rawValue: "refreshView"), object: nil, userInfo: nil)
  45. }
  46. override func viewDidLoad() {
  47. super.viewDidLoad()
  48. title = "Start Call".localized()
  49. if startWhiteBoard && startSS {
  50. title = "Start Whiteboard/Screen Sharing".localized()
  51. } else if onlyAudioOrVideo == 1 {
  52. title = "Start Audio Call".localized()
  53. } else if onlyAudioOrVideo == 2 {
  54. title = "Start Video Call".localized()
  55. } else if startWhiteBoard {
  56. title = "Start Whiteboard".localized()
  57. } else if startSS {
  58. title = "Start Screen Sharing".localized()
  59. }
  60. let attributes = [NSAttributedString.Key.font: UIFont.boldSystemFont(ofSize: 16.0), NSAttributedString.Key.foregroundColor: UIColor.white]
  61. self.navigationController?.navigationBar.titleTextAttributes = attributes
  62. if (isAddParticipantVideo) {
  63. title = "Friends".localized()
  64. } else {
  65. let cancel = UIBarButtonItem(title: "Cancel".localized(), style: .plain, target: self, action: #selector(didTapCancel(sender:)))
  66. navigationItem.leftBarButtonItem = cancel
  67. }
  68. let buttonAddFriend = UIBarButtonItem(image: UIImage(systemName: "person.badge.plus", withConfiguration: UIImage.SymbolConfiguration(pointSize: 18, weight: .regular, scale: .default))?.withTintColor(.white), style: .plain, target: self, action: #selector(addFriend(sender:)))
  69. navigationItem.rightBarButtonItem = buttonAddFriend
  70. getData()
  71. dataPersonNotChange = dataPerson
  72. searchController = UISearchController(searchResultsController: nil)
  73. searchController.delegate = self
  74. searchController.searchResultsUpdater = self
  75. searchController.searchBar.autocapitalizationType = .none
  76. searchController.searchBar.delegate = self
  77. searchController.obscuresBackgroundDuringPresentation = false
  78. searchController.searchBar.searchTextField.attributedPlaceholder = NSAttributedString(string: "Search".localized(), attributes: [NSAttributedString.Key.foregroundColor: UIColor.gray, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)])
  79. // searchController.searchBar.updateHeight(height: 36, radius: 18)
  80. // searchController.searchBar.setMagnifyingGlassColorTo(color: .white)
  81. searchController.searchBar.setImage(UIImage(), for: .search, state: .normal)
  82. searchController.searchBar.setPositionAdjustment(UIOffset(horizontal: 10, vertical: 0), for: .search)
  83. searchController.searchBar.setCustomBackgroundImage(image: UIImage(named: self.traitCollection.userInterfaceStyle == .dark ? "nx_search_bar_dark" : "nx_search_bar", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!)
  84. searchController.searchBar.tintColor = .mainColor
  85. navigationItem.searchController = searchController
  86. navigationItem.hidesSearchBarWhenScrolling = false
  87. definesPresentationContext = true
  88. tableView.delegate = self
  89. tableView.dataSource = self
  90. let center: NotificationCenter = NotificationCenter.default
  91. center.addObserver(self, selector: #selector(refresh(notification:)), name: NSNotification.Name(rawValue: "onUpdatePersonInfo"), object: nil)
  92. }
  93. @objc func addFriend(sender: UIBarButtonItem) {
  94. let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "addFriendNav") as! UINavigationController
  95. Utils.addBackground(view: controller.view)
  96. if let vc = controller.viewControllers.first as? AddFriendTableViewController {
  97. vc.isDismiss = {
  98. self.getData()
  99. self.dataPersonNotChange = self.dataPerson
  100. self.tableView.reloadData()
  101. }
  102. }
  103. self.navigationController?.present(controller, animated: true, completion: nil)
  104. }
  105. @objc func refresh(notification: NSNotification) {
  106. DispatchQueue.main.async {
  107. //print("MASuK SINI DONG")
  108. self.getData()
  109. self.dataPersonNotChange = self.dataPerson
  110. self.tableView.reloadData()
  111. }
  112. }
  113. @objc func didTapCancel(sender: AnyObject) {
  114. navigationController?.dismiss(animated: true, completion: nil)
  115. }
  116. @objc func didTapBroadcastButton(sender: AnyObject){
  117. }
  118. func getData() {
  119. dataPerson.removeAll()
  120. let idMe = UserDefaults.standard.string(forKey: "me") as String?
  121. Database.shared.database?.inTransaction({ (fmdb, rollback) in
  122. if let cursorData = Database.shared.getRecords(fmdb: fmdb, query: "SELECT f_pin, first_name, last_name, official_account, image_id, device_id, offline_mode, user_type, ex_block, ex_offmp FROM BUDDY where official_account<>'1' and f_pin <> '\(idMe!)' order by 4 desc, 2 collate nocase asc") {
  123. while cursorData.next() {
  124. var row: [String: String?] = [:]
  125. row["f_pin"] = cursorData.string(forColumnIndex: 0)
  126. if(connectedCall.count > 0 && connectedCall.contains(where: { $0["f_pin"] == row["f_pin"] })) {
  127. continue
  128. }
  129. var name = ""
  130. if let firstname = cursorData.string(forColumnIndex: 1) {
  131. name = firstname
  132. }
  133. if let lastname = cursorData.string(forColumnIndex: 2) {
  134. name = name + " " + lastname
  135. }
  136. if name.trimmingCharacters(in: .whitespaces) == "USR\(row["f_pin"]!!)" {
  137. continue
  138. }
  139. row["block"] = cursorData.string(forColumnIndex: 8)
  140. if row["block"] == "1" || row["block"] == "-1" {
  141. continue
  142. }
  143. row["name"] = name
  144. row["picture"] = cursorData.string(forColumnIndex: 4)
  145. row["isOfficial"] = cursorData.string(forColumnIndex: 3)
  146. row["deviceId"] = cursorData.string(forColumnIndex: 5)
  147. row["isOffline"] = cursorData.string(forColumnIndex: 6)
  148. row["user_type"] = cursorData.string(forColumnIndex: 7)
  149. row["ex_offmp"] = cursorData.string(forColumnIndex: 7)
  150. dataPerson.append(row)
  151. }
  152. cursorData.close()
  153. }
  154. })
  155. }
  156. func filterContentForSearchText(_ searchText: String) {
  157. fillteredData = self.dataPerson.filter { $0["name"]!!.lowercased().contains(searchText.lowercased()) }
  158. tableView.reloadData()
  159. }
  160. }
  161. extension ContactCallViewController: UITableViewDelegate {
  162. func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  163. if startWhiteBoard && startSS {
  164. return
  165. } else if (isAddParticipantVideo) {
  166. self.dismiss(animated: true, completion: {
  167. self.isDismiss?(self.dataPerson[indexPath.row] as [String: String?])
  168. })
  169. } else if startWhiteBoard {
  170. if !CheckConnection.isConnectedToNetwork() {
  171. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  172. imageView.tintColor = .white
  173. let banner = FloatingNotificationBanner(title: "Check your connection".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)
  174. banner.show()
  175. return
  176. }
  177. let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "wbVC") as! WhiteboardViewController
  178. controller.modalPresentationStyle = .overFullScreen
  179. controller.fromContact = 0
  180. controller.user = User.getData(pin: self.dataPerson[indexPath.row]["f_pin"]!!)
  181. present(controller, animated: true, completion: nil)
  182. } else if startSS {
  183. if !CheckConnection.isConnectedToNetwork() {
  184. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  185. imageView.tintColor = .white
  186. let banner = FloatingNotificationBanner(title: "Check your connection".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)
  187. banner.show()
  188. return
  189. }
  190. let controller = ScreenSharingViewController()
  191. controller.modalPresentationStyle = .overFullScreen
  192. controller.fromContact = 0
  193. controller.user = User.getData(pin: self.dataPerson[indexPath.row]["f_pin"]!!)
  194. present(controller, animated: true, completion: nil)
  195. }
  196. }
  197. }
  198. extension ContactCallViewController: UITableViewDataSource {
  199. func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
  200. return 60
  201. }
  202. func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  203. if isFilltering {
  204. return fillteredData.count
  205. }
  206. return dataPersonNotChange.count
  207. }
  208. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  209. let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath ) as! ContactCallCell
  210. cell.imagePerson.layer.masksToBounds = false
  211. cell.imagePerson.circle()
  212. cell.imagePerson.clipsToBounds = true
  213. cell.imagePerson.image = UIImage(named: "Profile---Purple", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)
  214. cell.imagePerson.contentMode = .scaleAspectFit
  215. if isFilltering {
  216. dataPerson = fillteredData
  217. } else {
  218. dataPerson = dataPersonNotChange
  219. }
  220. if dataPerson.count > 0 {
  221. let pictureImage = dataPerson[indexPath.row]["picture"]!
  222. if (pictureImage != "" && pictureImage != nil) {
  223. cell.imagePerson.setImage(name: pictureImage!)
  224. cell.imagePerson.contentMode = .scaleAspectFill
  225. }
  226. cell.selectionStyle = UITableViewCell.SelectionStyle.none
  227. if User.isOfficial(official_account: (dataPerson[indexPath.row]["isOfficial"] ?? "")!) || User.isOfficialRegular(official_account: (dataPerson[indexPath.row]["isOfficial"] ?? "")!) {
  228. cell.namePerson.attributedText = self.set(image: UIImage(named: "ic_official_flag", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!, with: " \(dataPerson[indexPath.row]["name"]!!)", size: 15, y: -4, colorText: UIColor.officialColor)
  229. } else if User.isVerified(official_account: (dataPerson[indexPath.row]["isOfficial"] ?? "")!) {
  230. cell.namePerson.attributedText = self.set(image: UIImage(named: "ic_verified", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!, with: " \(dataPerson[indexPath.row]["name"]!!)", size: 15, y: -4, colorText: UIColor.verifiedColor)
  231. }
  232. else if User.isInternal(userType: (dataPerson[indexPath.row]["user_type"] ?? "")!) {
  233. cell.namePerson.attributedText = self.set(image: UIImage(named: "ic_internal", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!, with: " \(dataPerson[indexPath.row]["name"]!!)", size: 15, y: -4, colorText: UIColor.internalColor)
  234. } else if User.isCallCenter(userType: (dataPerson[indexPath.row]["user_type"] ?? "")!) {
  235. let dataCategory = CategoryCC.getDataFromServiceId(service_id: (dataPerson[indexPath.row]["ex_offmp"] ?? "")!)
  236. if dataCategory != nil {
  237. cell.namePerson.attributedText = self.set(image: UIImage(named: "pb_call_center", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!, with: " \(dataPerson[indexPath.row]["name"]!!) (\(dataCategory!.service_name))", size: 15, y: -4, colorText: UIColor.ccColor)
  238. } else {
  239. cell.namePerson.attributedText = self.set(image: UIImage(named: "pb_call_center", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!, with: " \(dataPerson[indexPath.row]["name"]!!)", size: 15, y: -4, colorText: UIColor.ccColor)
  240. }
  241. } else {
  242. cell.namePerson.text = dataPerson[indexPath.row]["name"] as? String
  243. }
  244. if startWhiteBoard && startSS {
  245. cell.audioCallButton.tag = indexPath.row
  246. cell.videoCallButton.tag = indexPath.row
  247. cell.audioCallButton.setImage(UIImage(named: "pb_screen_share", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!.withTintColor(.mainColor).resize(target: CGSize(width: 35, height: 35)), for: .normal)
  248. cell.videoCallButton.setImage(UIImage(named: "pb_whiteboard", in: Bundle.resourceBundle(for: Nexilis.self), with: nil)!.withTintColor(.mainColor).resize(target: CGSize(width: 25, height: 25)), for: .normal)
  249. cell.audioCallButton.addTarget(self, action: #selector(SS(sender:)), for: .touchUpInside)
  250. cell.videoCallButton.addTarget(self, action: #selector(WB(sender:)), for: .touchUpInside)
  251. } else if onlyAudioOrVideo == 1 {
  252. if cell.videoCallButton != nil && cell.videoCallButton.isDescendant(of: cell) {
  253. cell.videoCallButton.removeFromSuperview()
  254. cell.audioCallButton.removeConstraints(cell.audioCallButton.constraints)
  255. cell.audioCallButton.anchor(right: cell.rightAnchor, paddingRight: 20.0, centerY: cell.centerYAnchor)
  256. }
  257. } else if startWhiteBoard || startSS {
  258. cell.audioCallButton.isHidden = true
  259. cell.videoCallButton.isHidden = true
  260. } else if onlyAudioOrVideo == 2 {
  261. cell.audioCallButton.isHidden = true
  262. } else if (isAddParticipantVideo) {
  263. cell.audioCallButton.isHidden = true
  264. cell.videoCallButton.isHidden = true
  265. } else {
  266. cell.audioCallButton.tag = indexPath.row
  267. cell.videoCallButton.tag = indexPath.row
  268. cell.audioCallButton.addTarget(self, action: #selector(call(sender:)), for: .touchUpInside)
  269. cell.videoCallButton.addTarget(self, action: #selector(videoCall(sender:)), for: .touchUpInside)
  270. }
  271. }
  272. return cell
  273. }
  274. @objc func call(sender: Any) {
  275. let index = sender as! UIButton
  276. if let pin = dataPerson[index.tag]["f_pin"] {
  277. if !CheckConnection.isConnectedToNetwork() {
  278. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  279. imageView.tintColor = .white
  280. let banner = FloatingNotificationBanner(title: "Check your connection".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)
  281. banner.show()
  282. return
  283. }
  284. let controller = QmeraAudioViewController()
  285. controller.user = User.getData(pin: pin)
  286. controller.isOutgoing = true
  287. controller.modalPresentationStyle = .overFullScreen
  288. present(controller, animated: true, completion: nil)
  289. }
  290. }
  291. @objc func videoCall(sender: Any) {
  292. let index = sender as! UIButton
  293. if !CheckConnection.isConnectedToNetwork() {
  294. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  295. imageView.tintColor = .white
  296. let banner = FloatingNotificationBanner(title: "Check your connection".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)
  297. banner.show()
  298. return
  299. }
  300. let videoVC = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "videoVCQmera") as! QmeraVideoViewController
  301. videoVC.dataPerson.append(dataPerson[index.tag])
  302. videoVC.modalPresentationStyle = .overFullScreen
  303. self.show(videoVC, sender: nil)
  304. }
  305. @objc func WB(sender: Any) {
  306. let index = sender as! UIButton
  307. if let pin = dataPerson[index.tag]["f_pin"] {
  308. if !CheckConnection.isConnectedToNetwork() {
  309. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  310. imageView.tintColor = .white
  311. let banner = FloatingNotificationBanner(title: "Check your connection".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)
  312. banner.show()
  313. return
  314. }
  315. let controller = AppStoryBoard.Palio.instance.instantiateViewController(identifier: "wbVC") as! WhiteboardViewController
  316. controller.modalPresentationStyle = .overFullScreen
  317. controller.fromContact = 0
  318. controller.user = User.getData(pin: pin)
  319. present(controller, animated: true, completion: nil)
  320. }
  321. }
  322. @objc func SS(sender: Any) {
  323. let index = sender as! UIButton
  324. if let pin = dataPerson[index.tag]["f_pin"] {
  325. if !CheckConnection.isConnectedToNetwork() {
  326. let imageView = UIImageView(image: UIImage(systemName: "xmark.circle.fill"))
  327. imageView.tintColor = .white
  328. let banner = FloatingNotificationBanner(title: "Check your connection".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)
  329. banner.show()
  330. return
  331. }
  332. let controller = ScreenSharingViewController()
  333. controller.modalPresentationStyle = .overFullScreen
  334. controller.fromContact = 0
  335. controller.user = User.getData(pin: pin)
  336. present(controller, animated: true, completion: nil)
  337. }
  338. }
  339. }
  340. class ContactCallCell: UITableViewCell {
  341. @IBOutlet weak var imagePerson: UIImageView!
  342. @IBOutlet weak var videoCallButton: UIButton!
  343. @IBOutlet weak var audioCallButton: UIButton!
  344. @IBOutlet weak var namePerson: UILabel!
  345. }
  346. extension ContactCallViewController {
  347. func set(image: UIImage, with text: String, size: CGFloat, y: CGFloat, colorText: UIColor = UIColor.black) -> NSAttributedString {
  348. let attachment = NSTextAttachment()
  349. attachment.image = image
  350. attachment.bounds = CGRect(x: 0, y: y, width: size, height: size)
  351. let attachmentStr = NSAttributedString(attachment: attachment)
  352. let mutableAttributedString = NSMutableAttributedString()
  353. mutableAttributedString.append(attachmentStr)
  354. let attributedStringColor = [NSAttributedString.Key.foregroundColor : colorText]
  355. let textString = NSAttributedString(string: text, attributes: attributedStringColor)
  356. mutableAttributedString.append(textString)
  357. return mutableAttributedString
  358. }
  359. }
  360. extension ContactCallViewController: UISearchControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating {
  361. func updateSearchResults(for searchController: UISearchController) {
  362. filterContentForSearchText(searchController.searchBar.text!.trimmingCharacters(in: .whitespacesAndNewlines))
  363. }
  364. func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
  365. searchBar.showsCancelButton = true
  366. let cBtn = searchBar.value(forKey: "cancelButton") as! UIButton
  367. cBtn.setTitle("Cancel".localized(), for: .normal)
  368. }
  369. func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
  370. searchBar.showsCancelButton = false
  371. }
  372. }