AddFriendTableViewController.swift 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260
  1. //
  2. // AddFriendTableViewController.swift
  3. // Qmera
  4. //
  5. // Created by Yayan Dwi on 23/09/21.
  6. //
  7. import UIKit
  8. class AddFriendTableViewController: UITableViewController {
  9. var searchController: UISearchController!
  10. var data: [User] = []
  11. var fillteredData: [User] = []
  12. var isSearchBarEmpty: Bool {
  13. return searchController.searchBar.text!.trimmingCharacters(in: .whitespacesAndNewlines).isEmpty
  14. }
  15. var isFilltering: Bool {
  16. return searchController.isActive && !isSearchBarEmpty
  17. }
  18. var isDismiss: (() -> ())?
  19. var timerSearch: Timer?
  20. func filterContentForSearchText(_ searchText: String) {
  21. fillteredData = data.filter{ $0.fullName.lowercased().contains(searchText.lowercased()) }
  22. getDataSearch(searchText: searchText) { data in
  23. let r = data.filter { $0.fullName.lowercased().contains(searchText.lowercased()) }
  24. self.fillteredData.append(contentsOf: r.filter { !self.fillteredData.contains($0) })
  25. DispatchQueue.main.async {
  26. self.tableView.reloadData()
  27. }
  28. }
  29. tableView.reloadData()
  30. }
  31. override func viewDidDisappear(_ animated: Bool) {
  32. isDismiss?()
  33. }
  34. override func viewDidLoad() {
  35. super.viewDidLoad()
  36. title = "Add Friends".localized()
  37. let attributes = [NSAttributedString.Key.foregroundColor: UIColor.white]
  38. let navBarAppearance = UINavigationBarAppearance()
  39. navBarAppearance.configureWithOpaqueBackground()
  40. navBarAppearance.backgroundColor = self.traitCollection.userInterfaceStyle == .dark ? .blackDarkMode : UIColor.mainColor
  41. navBarAppearance.titleTextAttributes = attributes
  42. navigationController?.navigationBar.standardAppearance = navBarAppearance
  43. navigationController?.navigationBar.scrollEdgeAppearance = navBarAppearance
  44. navigationItem.leftBarButtonItem = UIBarButtonItem(title: "Cancel".localized(), style: .plain, target: self, action: #selector(cancel(sender:)))
  45. navigationItem.rightBarButtonItem = UIBarButtonItem(title: "Scan QR".localized(), style: .plain, target: self, action: #selector(scanQR(sender:)))
  46. searchController = UISearchController(searchResultsController: nil)
  47. searchController.delegate = self
  48. searchController.searchResultsUpdater = self
  49. searchController.searchBar.autocapitalizationType = .none
  50. searchController.searchBar.delegate = self
  51. searchController.obscuresBackgroundDuringPresentation = false
  52. searchController.searchBar.searchTextField.attributedPlaceholder = NSAttributedString(string: "Search".localized(), attributes: [NSAttributedString.Key.foregroundColor: UIColor.gray, NSAttributedString.Key.font: UIFont.systemFont(ofSize: 16)])
  53. // searchController.searchBar.updateHeight(height: 36, radius: 18)
  54. // searchController.searchBar.setMagnifyingGlassColorTo(color: .white)
  55. searchController.searchBar.setImage(UIImage(), for: .search, state: .normal)
  56. searchController.searchBar.setPositionAdjustment(UIOffset(horizontal: 10, vertical: 0), for: .search)
  57. 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)!)
  58. searchController.searchBar.tintColor = .mainColor
  59. definesPresentationContext = true
  60. navigationItem.searchController = searchController
  61. navigationItem.hidesSearchBarWhenScrolling = false
  62. tableView.tableFooterView = UIView()
  63. self.data.removeAll()
  64. getData { d in
  65. self.data = d
  66. DispatchQueue.main.async {
  67. self.tableView.reloadData()
  68. }
  69. }
  70. }
  71. @objc func cancel(sender: Any) {
  72. navigationController?.dismiss(animated: true, completion: nil)
  73. }
  74. @objc func scanQR(sender: Any) {
  75. let scannerVC = QRScannerController()
  76. scannerVC.onQRCodeDetected = { qrCode in
  77. print("Detected QR Code: \(qrCode)")
  78. self.dismiss(animated: true)
  79. var isQR = false
  80. DispatchQueue.main.async {
  81. var dataMessage = CoreMessage_TMessageBank.getAddFriendQRCode(fpin: qrCode)
  82. if Nexilis.checkingAccess(key: "friend_request_approval"){
  83. dataMessage = CoreMessage_TMessageBank.getAddFriendRequest(fPin: qrCode)
  84. }
  85. if let response = Nexilis.writeAndWait(message: dataMessage, timeout: 1000 * 30) {
  86. print(response.toLogString())
  87. isQR = true
  88. }
  89. if isQR {
  90. let alert = UIAlertController(title: "Action Successful".localized(), message: Nexilis.checkingAccess(key: "friend_request_approval") ? "Friend request has been sent".localized() : "Successfully added a new friend".localized(), preferredStyle: .alert)
  91. alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
  92. self.present(alert, animated: true, completion: nil)
  93. }
  94. else {
  95. let alert = UIAlertController(title: "Unable to complete action".localized(), message: "Friend is invalid or not found".localized(), preferredStyle: .alert)
  96. alert.addAction(UIAlertAction(title: "OK", style: .default, handler: nil))
  97. self.present(alert, animated: true, completion: nil)
  98. }
  99. }
  100. }
  101. present(scannerVC, animated: true, completion: nil)
  102. }
  103. // MARK: - Data source
  104. func getData(completion: @escaping ([User])->()) {
  105. DispatchQueue.global().async {
  106. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getPersonSuggestion(p_last_seq: "0")),
  107. response.isOk() {
  108. let data = response.getBody(key: CoreMessage_TMessageKey.DATA)
  109. guard !data.isEmpty else {
  110. return
  111. }
  112. if let jsonArray = try! JSONSerialization.jsonObject(with: data.data(using: .utf8)!, options: []) as? [[String: String?]] {
  113. var users = jsonArray.map { json in
  114. User(pin: (json[CoreMessage_TMessageKey.F_PIN] ?? "") ?? "",
  115. firstName: (json[CoreMessage_TMessageKey.FIRST_NAME] ?? "") ?? "",
  116. lastName: (json[CoreMessage_TMessageKey.LAST_NAME] ?? "") ?? "",
  117. thumb: (json[CoreMessage_TMessageKey.THUMB_ID] ?? "") ?? "")
  118. }
  119. users = users.filter({ $0.fullName != "USR\($0.pin)" })
  120. completion(users)
  121. }
  122. }
  123. }
  124. }
  125. func getDataSearch(searchText: String, completion: @escaping ([User]) -> ()) {
  126. DispatchQueue.global().async {
  127. if let response = Nexilis.writeSync(message: CoreMessage_TMessageBank.getSearchFriend(search_keyword: searchText, limit: "10")), response.isOk() {
  128. let data = response.getBody(key: CoreMessage_TMessageKey.DATA)
  129. guard !data.isEmpty else {
  130. return
  131. }
  132. if let jsonArray = try! JSONSerialization.jsonObject(with: data.data(using: .utf8)!, options: []) as? [[String: String?]] {
  133. var users = jsonArray.map { json in
  134. User(pin: (json[CoreMessage_TMessageKey.F_PIN] ?? "") ?? "",
  135. firstName: (json[CoreMessage_TMessageKey.FIRST_NAME] ?? "") ?? "",
  136. lastName: (json[CoreMessage_TMessageKey.LAST_NAME] ?? "") ?? "",
  137. thumb: (json[CoreMessage_TMessageKey.THUMB_ID] ?? "") ?? "")
  138. }
  139. users = users.filter({ $0.fullName != "USR\($0.pin)" })
  140. completion(users)
  141. }
  142. }
  143. }
  144. }
  145. func searchBarTextDidBeginEditing(_ searchBar: UISearchBar) {
  146. searchBar.showsCancelButton = true
  147. let cBtn = searchBar.value(forKey: "cancelButton") as! UIButton
  148. cBtn.setTitle("Cancel".localized(), for: .normal)
  149. }
  150. func searchBarTextDidEndEditing(_ searchBar: UISearchBar) {
  151. searchBar.showsCancelButton = false
  152. }
  153. // MARK: - Table view data source
  154. override func tableView(_ tableView: UITableView, titleForHeaderInSection section: Int) -> String? {
  155. return "Suggestions".localized()
  156. }
  157. override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  158. let user: User
  159. if isFilltering {
  160. user = fillteredData[indexPath.row]
  161. } else {
  162. user = data[indexPath.row]
  163. }
  164. let controller = AppStoryBoard.Palio.instance.instantiateViewController(withIdentifier: "profileView") as! ProfileViewController
  165. controller.flag = .invite
  166. controller.data = user.pin
  167. controller.name = user.fullName
  168. controller.picture = user.thumb
  169. controller.isDismiss = {
  170. self.data.removeAll(where: {$0.pin == user.pin})
  171. if self.isFilltering {
  172. self.fillteredData.removeAll(where: {$0.pin == user.pin})
  173. }
  174. self.tableView.reloadData()
  175. // self.getData { d in
  176. // self.data = d
  177. // DispatchQueue.main.async {
  178. // self.tableView.reloadData()
  179. // }
  180. // }
  181. }
  182. navigationController?.show(controller, sender: nil)
  183. }
  184. override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  185. if isFilltering {
  186. return fillteredData.count
  187. }
  188. return data.count
  189. }
  190. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  191. let cell = tableView.dequeueReusableCell(withIdentifier: "reuseIdentifier", for: indexPath)
  192. var content = cell.defaultContentConfiguration()
  193. let user: User
  194. if isFilltering {
  195. user = fillteredData[indexPath.row]
  196. } else {
  197. user = data[indexPath.row]
  198. }
  199. content.imageProperties.maximumSize = CGSize(width: 40, height: 40)
  200. getImage(name: user.thumb, placeholderImage: UIImage(named: "Profile---Purple", in: Bundle.resourceBundle(for: Nexilis.self), with: nil), isCircle: true, tableView: tableView, indexPath: indexPath, completion: { result, isDownloaded, image in
  201. content.image = image
  202. })
  203. content.text = user.fullName
  204. content.textProperties.font = UIFont.systemFont(ofSize: 14)
  205. cell.contentConfiguration = content
  206. return cell
  207. }
  208. }
  209. // MARK: - Extension
  210. extension AddFriendTableViewController: UISearchControllerDelegate, UISearchBarDelegate, UISearchResultsUpdating {
  211. func updateSearchResults(for searchController: UISearchController) {
  212. timerSearch?.invalidate()
  213. let currentText = searchController.searchBar.text!.trimmingCharacters(in: .whitespacesAndNewlines)
  214. if currentText.count >= 2 || currentText.isEmpty {
  215. timerSearch = Timer.scheduledTimer(withTimeInterval: 0.5, repeats: false, block: {_ in
  216. self.filterContentForSearchText(currentText)
  217. })
  218. }
  219. }
  220. }