ChatListController.swift 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202
  1. import UIKit
  2. class ChatListController: UIViewController {
  3. weak var coordinator: ChatListCoordinator?
  4. var chatList: DCChatList?
  5. lazy var chatTable: UITableView = {
  6. let chatTable = UITableView()
  7. chatTable.dataSource = self
  8. chatTable.delegate = self
  9. chatTable.rowHeight = 80
  10. return chatTable
  11. }()
  12. var msgChangedObserver: Any?
  13. var incomingMsgObserver: Any?
  14. var viewChatObserver: Any?
  15. var newButton: UIBarButtonItem!
  16. override func viewWillAppear(_ animated: Bool) {
  17. super.viewWillAppear(animated)
  18. if #available(iOS 11.0, *) {
  19. navigationController?.navigationBar.prefersLargeTitles = true
  20. navigationItem.largeTitleDisplayMode = .always
  21. }
  22. getChatList()
  23. }
  24. override func viewWillDisappear(_ animated: Bool) {
  25. super.viewWillDisappear(animated)
  26. if #available(iOS 11.0, *) {
  27. navigationController?.navigationBar.prefersLargeTitles = false
  28. }
  29. }
  30. override func viewDidAppear(_ animated: Bool) {
  31. super.viewDidAppear(animated)
  32. let nc = NotificationCenter.default
  33. msgChangedObserver = nc.addObserver(forName: dcNotificationChanged,
  34. object: nil, queue: nil) {
  35. _ in
  36. self.getChatList()
  37. }
  38. incomingMsgObserver = nc.addObserver(forName: dcNotificationIncoming,
  39. object: nil, queue: nil) {
  40. _ in
  41. self.getChatList()
  42. }
  43. viewChatObserver = nc.addObserver(forName: dcNotificationViewChat, object: nil, queue: nil) {
  44. notification in
  45. if let chatId = notification.userInfo?["chat_id"] as? Int {
  46. self.coordinator?.showChat(chatId: chatId)
  47. }
  48. }
  49. }
  50. override func viewDidDisappear(_ animated: Bool) {
  51. super.viewDidDisappear(animated)
  52. let nc = NotificationCenter.default
  53. if let msgChangedObserver = self.msgChangedObserver {
  54. nc.removeObserver(msgChangedObserver)
  55. }
  56. if let incomingMsgObserver = self.incomingMsgObserver {
  57. nc.removeObserver(incomingMsgObserver)
  58. }
  59. if let viewChatObserver = self.viewChatObserver {
  60. nc.removeObserver(viewChatObserver)
  61. }
  62. }
  63. override func viewDidLoad() {
  64. super.viewDidLoad()
  65. title = String.localized("pref_chats")
  66. navigationController?.navigationBar.prefersLargeTitles = true
  67. newButton = UIBarButtonItem(barButtonSystemItem: UIBarButtonItem.SystemItem.compose, target: self, action: #selector(didPressNewChat))
  68. newButton.tintColor = DCColors.primary
  69. navigationItem.rightBarButtonItem = newButton
  70. setupChatTable()
  71. }
  72. private func setupChatTable() {
  73. view.addSubview(chatTable)
  74. chatTable.translatesAutoresizingMaskIntoConstraints = false
  75. chatTable.topAnchor.constraint(equalTo: view.topAnchor).isActive = true
  76. chatTable.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
  77. chatTable.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
  78. chatTable.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
  79. }
  80. @objc func didPressNewChat() {
  81. coordinator?.showNewChatController()
  82. }
  83. func getChatList() {
  84. guard let chatlistPointer = dc_get_chatlist(mailboxPointer, DC_GCL_NO_SPECIALS, nil, 0) else {
  85. fatalError("chatlistPointer was nil")
  86. }
  87. // ownership of chatlistPointer transferred here to ChatList object
  88. chatList = DCChatList(chatListPointer: chatlistPointer)
  89. chatTable.reloadData()
  90. }
  91. }
  92. extension ChatListController: UITableViewDataSource, UITableViewDelegate {
  93. func tableView(_: UITableView, numberOfRowsInSection _: Int) -> Int {
  94. guard let chatList = self.chatList else {
  95. fatalError("chatList was nil in data source")
  96. }
  97. return chatList.length
  98. }
  99. func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
  100. let row = indexPath.row
  101. guard let chatList = self.chatList else {
  102. fatalError("chatList was nil in data source")
  103. }
  104. let cell: ContactCell
  105. if let c = tableView.dequeueReusableCell(withIdentifier: "ChatCell") as? ContactCell {
  106. cell = c
  107. } else {
  108. cell = ContactCell(style: .default, reuseIdentifier: "ChatCell")
  109. }
  110. let chatId = chatList.getChatId(index: row)
  111. let chat = DCChat(id: chatId)
  112. let summary = chatList.summary(index: row)
  113. cell.nameLabel.text = chat.name
  114. if let img = chat.profileImage {
  115. cell.setImage(img)
  116. } else {
  117. cell.setBackupImage(name: chat.name, color: chat.color)
  118. }
  119. cell.setVerified(isVerified: chat.isVerified)
  120. let result1 = summary.text1 ?? ""
  121. let result2 = summary.text2 ?? ""
  122. let result: String
  123. if !result1.isEmpty, !result2.isEmpty {
  124. result = "\(result1): \(result2)"
  125. } else {
  126. result = "\(result1)\(result2)"
  127. }
  128. cell.emailLabel.text = result
  129. cell.setTimeLabel(summary.timeStamp)
  130. cell.setDeliveryStatusIndicator(summary.state)
  131. return cell
  132. }
  133. func tableView(_: UITableView, didSelectRowAt indexPath: IndexPath) {
  134. let row = indexPath.row
  135. if let chatId = chatList?.getChatId(index: row) {
  136. coordinator?.showChat(chatId: chatId)
  137. }
  138. }
  139. func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath) -> [UITableViewRowAction]? {
  140. let row = indexPath.row
  141. guard let chatList = chatList else {
  142. return nil
  143. }
  144. // assigning swipe by delete to chats
  145. let delete = UITableViewRowAction(style: .destructive, title: String.localized("global_menu_edit_delete_desktop")) { [unowned self] _, indexPath in
  146. let chatId = chatList.getChatId(index: row)
  147. self.showDeleteChatConfirmationAlert(chatId: chatId)
  148. }
  149. delete.backgroundColor = UIColor.red
  150. return [delete]
  151. }
  152. }
  153. extension ChatListController {
  154. private func showDeleteChatConfirmationAlert(chatId: Int) {
  155. let alert = UIAlertController(
  156. title: String.localized("ask_delete_chat_desktop"),
  157. message: nil,
  158. preferredStyle: .alert
  159. )
  160. alert.addAction(UIAlertAction(title: String.localized("global_menu_edit_delete_desktop"), style: .default, handler: { action in
  161. self.deleteChat(chatId: chatId)
  162. }))
  163. alert.addAction(UIAlertAction(title: String.localized("cancel"), style: .cancel, handler: nil))
  164. self.present(alert, animated: true, completion: nil)
  165. }
  166. private func deleteChat(chatId: Int) {
  167. dc_delete_chat(mailboxPointer, UInt32(chatId))
  168. self.getChatList()
  169. }
  170. }