OpenConversationsTableViewController.swift 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180
  1. //
  2. // SPDX-FileCopyrightText: 2023 Nextcloud GmbH and Nextcloud contributors
  3. // SPDX-License-Identifier: GPL-3.0-or-later
  4. //
  5. import UIKit
  6. class OpenConversationsTableViewController: UITableViewController, UISearchResultsUpdating {
  7. var openConversations: [NCRoom] = []
  8. var filteredConversations: [NCRoom] = []
  9. var didTriggerInitialSearch: Bool = false
  10. let tableBackgroundView: PlaceholderView = PlaceholderView()
  11. let searchController: UISearchController = UISearchController(searchResultsController: nil)
  12. override func viewDidLoad() {
  13. super.viewDidLoad()
  14. self.navigationController?.navigationBar.titleTextAttributes = [NSAttributedString.Key.foregroundColor: NCAppBranding.themeTextColor()]
  15. self.navigationController?.navigationBar.tintColor = NCAppBranding.themeTextColor()
  16. self.navigationController?.navigationBar.barTintColor = NCAppBranding.themeColor()
  17. self.navigationController?.navigationBar.isTranslucent = false
  18. self.navigationItem.title = NSLocalizedString("Open conversations", comment: "")
  19. let appearance = UINavigationBarAppearance()
  20. appearance.configureWithOpaqueBackground()
  21. appearance.titleTextAttributes = [.foregroundColor: NCAppBranding.themeTextColor()]
  22. appearance.backgroundColor = NCAppBranding.themeColor()
  23. self.navigationItem.standardAppearance = appearance
  24. self.navigationItem.compactAppearance = appearance
  25. self.navigationItem.scrollEdgeAppearance = appearance
  26. if #available(iOS 16.0, *) {
  27. self.navigationItem.preferredSearchBarPlacement = .stacked
  28. }
  29. self.tableView.separatorInset = UIEdgeInsets(top: 0, left: 64, bottom: 0, right: 0)
  30. self.tableView.register(UINib(nibName: kContactsTableCellNibName, bundle: nil), forCellReuseIdentifier: kContactCellIdentifier)
  31. tableBackgroundView.setImage(UIImage(named: "conversations-placeholder"))
  32. tableBackgroundView.placeholderTextView.text = NSLocalizedString("No results found", comment: "")
  33. tableBackgroundView.placeholderView.isHidden = true
  34. tableBackgroundView.loadingView.startAnimating()
  35. self.tableView.backgroundView = tableBackgroundView
  36. searchController.searchBar.placeholder = NSLocalizedString("Search", comment: "")
  37. searchController.searchResultsUpdater = self
  38. searchController.searchBar.sizeToFit()
  39. searchController.hidesNavigationBarDuringPresentation = false
  40. searchController.obscuresBackgroundDuringPresentation = false
  41. searchController.searchBar.tintColor = NCAppBranding.themeTextColor()
  42. if navigationController?.viewControllers.first == self {
  43. let barButtonItem = UIBarButtonItem(barButtonSystemItem: .cancel, target: self, action: nil)
  44. barButtonItem.primaryAction = UIAction(title: "", handler: { [unowned self] _ in
  45. self.dismiss(animated: true)
  46. })
  47. self.navigationItem.leftBarButtonItems = [barButtonItem]
  48. }
  49. if let searchTextField = searchController.searchBar.value(forKey: "searchField") as? UITextField {
  50. searchTextField.tintColor = NCAppBranding.themeTextColor()
  51. searchTextField.textColor = NCAppBranding.themeTextColor()
  52. DispatchQueue.main.async {
  53. // Search bar placeholder
  54. searchTextField.attributedPlaceholder = NSAttributedString(string: NSLocalizedString("Search", comment: ""),
  55. attributes: [NSAttributedString.Key.foregroundColor: NCAppBranding.themeTextColor().withAlphaComponent(0.5)])
  56. // Search bar search icon
  57. if let searchImageView = searchTextField.leftView as? UIImageView {
  58. searchImageView.image = searchImageView.image?.withRenderingMode(.alwaysTemplate)
  59. searchImageView.tintColor = NCAppBranding.themeTextColor().withAlphaComponent(0.5)
  60. }
  61. // Search bar search clear button
  62. if let clearButton = searchTextField.value(forKey: "_clearButton") as? UIButton {
  63. let clearButtonImage = clearButton.imageView?.image?.withRenderingMode(.alwaysTemplate)
  64. clearButton.setImage(clearButtonImage, for: .normal)
  65. clearButton.setImage(clearButtonImage, for: .highlighted)
  66. clearButton.tintColor = NCAppBranding.themeTextColor()
  67. }
  68. }
  69. }
  70. self.navigationItem.searchController = searchController
  71. self.navigationItem.searchController?.searchBar.searchTextField.backgroundColor = NCUtils.searchbarBGColor(forColor: NCAppBranding.themeColor())
  72. // Fix uisearchcontroller animation
  73. self.extendedLayoutIncludesOpaqueBars = true
  74. }
  75. override func viewWillAppear(_ animated: Bool) {
  76. self.navigationItem.hidesSearchBarWhenScrolling = false
  77. if !didTriggerInitialSearch {
  78. searchForListableRooms()
  79. didTriggerInitialSearch = true
  80. }
  81. }
  82. // MARK: - Search open conversations
  83. func searchForListableRooms() {
  84. NCAPIController.sharedInstance().getListableRooms(forAccount: NCDatabaseManager.sharedInstance().activeAccount(), withSerachTerm: "") { listableRooms, _ in
  85. self.tableBackgroundView.loadingView.stopAnimating()
  86. self.tableBackgroundView.loadingView.isHidden = true
  87. if let listableRooms {
  88. self.openConversations = listableRooms
  89. self.tableBackgroundView.placeholderView.isHidden = !listableRooms.isEmpty
  90. } else {
  91. self.tableBackgroundView.placeholderView.isHidden = false
  92. }
  93. self.tableView.reloadData()
  94. }
  95. }
  96. func filterConversationsWithSearchTerm(searchTerm: String) {
  97. if searchTerm.isEmpty {
  98. filteredConversations = openConversations
  99. } else {
  100. filteredConversations = openConversations.filter({ (room: NCRoom) -> Bool in
  101. return room.displayName!.range(of: searchTerm, options: NSString.CompareOptions.caseInsensitive) != nil
  102. })
  103. }
  104. self.tableBackgroundView.placeholderView.isHidden = !filteredConversations.isEmpty
  105. }
  106. func updateSearchResults(for searchController: UISearchController) {
  107. if let searchTerm = searchController.searchBar.text {
  108. filterConversationsWithSearchTerm(searchTerm: searchTerm)
  109. tableView.reloadData()
  110. }
  111. }
  112. // MARK: - Table view data source
  113. override func numberOfSections(in tableView: UITableView) -> Int {
  114. return 1
  115. }
  116. override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
  117. if searchController.isActive {
  118. return filteredConversations.count
  119. }
  120. return openConversations.count
  121. }
  122. override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  123. let cell = tableView.dequeueReusableCell(withIdentifier: kContactCellIdentifier) as? ContactsTableViewCell ??
  124. ContactsTableViewCell(style: .default, reuseIdentifier: kContactCellIdentifier)
  125. var openConversation = openConversations[indexPath.row]
  126. if searchController.isActive {
  127. openConversation = filteredConversations[indexPath.row]
  128. }
  129. cell.labelTitle.text = openConversation.displayName
  130. // Set group avatar as default avatar
  131. cell.contactImage.setGroupAvatar()
  132. // Try to get room avatar even though at the moment (Talk 17) it is not exposed
  133. cell.contactImage.setAvatar(for: openConversation)
  134. // Set description
  135. cell.setUserStatusMessage(openConversation.roomDescription, withIcon: nil)
  136. return cell
  137. }
  138. override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
  139. var openConversation = openConversations[indexPath.row]
  140. if searchController.isActive {
  141. openConversation = filteredConversations[indexPath.row]
  142. }
  143. NCUserInterfaceController.sharedInstance().presentConversationsList()
  144. NCRoomsManager.sharedInstance().startChat(in: openConversation)
  145. }
  146. }