ContactDetailViewModel.swift 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195
  1. import UIKit
  2. import DcCore
  3. class ContactDetailViewModel {
  4. let context: DcContext
  5. enum ProfileSections {
  6. case chatOptions
  7. case statusArea
  8. case sharedChats
  9. case chatActions
  10. }
  11. enum ChatOption {
  12. case gallery
  13. case documents
  14. case ephemeralMessages
  15. case muteChat
  16. case startChat
  17. }
  18. enum ChatAction {
  19. case archiveChat
  20. case showEncrInfo
  21. case blockContact
  22. case deleteChat
  23. }
  24. var contactId: Int
  25. // TODO: check if that is too inefficient (each bit read from contact, results in a database-query)
  26. var contact: DcContact {
  27. return context.getContact(id: contactId)
  28. }
  29. let chatId: Int
  30. var isSavedMessages: Bool
  31. var isDeviceTalk: Bool
  32. private let sharedChats: DcChatlist
  33. private var sections: [ProfileSections] = []
  34. private var chatActions: [ChatAction] = []
  35. private var chatOptions: [ChatOption] = []
  36. init(dcContext: DcContext, contactId: Int) {
  37. self.context = dcContext
  38. self.contactId = contactId
  39. self.chatId = dcContext.getChatIdByContactId(contactId: contactId)
  40. self.isSavedMessages = false
  41. self.isDeviceTalk = false
  42. if chatId != 0 {
  43. let dcChat = dcContext.getChat(chatId: chatId)
  44. isSavedMessages = dcChat.isSelfTalk
  45. isDeviceTalk = dcChat.isDeviceTalk
  46. }
  47. self.sharedChats = context.getChatlist(flags: 0, queryString: nil, queryId: contactId)
  48. sections.append(.chatOptions)
  49. if !self.isSavedMessages {
  50. let dcContact = context.getContact(id: contactId)
  51. if !dcContact.status.isEmpty {
  52. sections.append(.statusArea)
  53. }
  54. }
  55. if sharedChats.length > 0 && !isSavedMessages && !isDeviceTalk {
  56. sections.append(.sharedChats)
  57. }
  58. sections.append(.chatActions)
  59. if chatId != 0 {
  60. chatOptions = [.gallery, .documents]
  61. if !isDeviceTalk {
  62. chatOptions.append(.ephemeralMessages)
  63. }
  64. if !isSavedMessages {
  65. chatOptions.append(.muteChat)
  66. }
  67. if !isDeviceTalk {
  68. chatOptions.append(.startChat)
  69. }
  70. chatActions = [.archiveChat]
  71. if !isDeviceTalk && !isSavedMessages {
  72. chatActions.append(.showEncrInfo)
  73. chatActions.append(.blockContact)
  74. }
  75. chatActions.append(.deleteChat)
  76. } else {
  77. chatOptions = [.gallery, .documents, .startChat]
  78. chatActions = [.showEncrInfo, .blockContact]
  79. }
  80. }
  81. func typeFor(section: Int) -> ContactDetailViewModel.ProfileSections {
  82. return sections[section]
  83. }
  84. func chatActionFor(row: Int) -> ContactDetailViewModel.ChatAction {
  85. return chatActions[row]
  86. }
  87. func chatOptionFor(row: Int) -> ContactDetailViewModel.ChatOption {
  88. return chatOptions[row]
  89. }
  90. var chatIsArchived: Bool {
  91. return chatId != 0 && context.getChat(chatId: chatId).isArchived
  92. }
  93. var chatIsMuted: Bool {
  94. return chatId != 0 && context.getChat(chatId: chatId).isMuted
  95. }
  96. var chatIsEphemeral: Bool {
  97. return chatId != 0 && context.getChatEphemeralTimer(chatId: chatId) > 0
  98. }
  99. var galleryItemMessageIds: [Int] {
  100. return context.getChatMedia(
  101. chatId: chatId,
  102. messageType: DC_MSG_IMAGE,
  103. messageType2: DC_MSG_GIF,
  104. messageType3: DC_MSG_VIDEO
  105. )
  106. }
  107. var documentItemMessageIds: [Int] {
  108. return context.getChatMedia(
  109. chatId: chatId,
  110. messageType: DC_MSG_FILE,
  111. messageType2: DC_MSG_AUDIO,
  112. messageType3: 0
  113. )
  114. }
  115. var numberOfSections: Int {
  116. return sections.count
  117. }
  118. func numberOfRowsInSection(_ section: Int) -> Int {
  119. switch sections[section] {
  120. case .chatOptions: return chatOptions.count
  121. case .statusArea: return 1
  122. case .sharedChats: return sharedChats.length
  123. case .chatActions: return chatActions.count
  124. }
  125. }
  126. func getSharedChatIdAt(indexPath: IndexPath) -> Int {
  127. let index = indexPath.row
  128. return sharedChats.getChatId(index: index)
  129. }
  130. func update(sharedChatCell cell: ContactCell, row index: Int) {
  131. let chatId = sharedChats.getChatId(index: index)
  132. let summary = sharedChats.getSummary(index: index)
  133. let unreadMessages = context.getUnreadMessages(chatId: chatId)
  134. let cellData = ChatCellData(chatId: chatId, highlightMsgId: nil, summary: summary, unreadMessages: unreadMessages)
  135. let cellViewModel = ChatCellViewModel(dcContext: context, chatData: cellData)
  136. cell.updateCell(cellViewModel: cellViewModel)
  137. }
  138. func titleFor(section: Int) -> String? {
  139. switch sections[section] {
  140. case .chatOptions: return nil
  141. case .statusArea: return String.localized("pref_default_status_label")
  142. case .sharedChats: return String.localized("profile_shared_chats")
  143. case .chatActions: return nil
  144. }
  145. }
  146. // returns true if chat is archived after action
  147. func toggleArchiveChat() -> Bool {
  148. if chatId == 0 {
  149. safe_fatalError("there is no chatId - you are probably are calling this from ContactDetail - this should be only called from ChatDetail")
  150. return false
  151. }
  152. let isArchivedBefore = chatIsArchived
  153. if !isArchivedBefore {
  154. NotificationManager.removeNotificationsForChat(dcContext: context, chatId: chatId)
  155. }
  156. context.archiveChat(chatId: chatId, archive: !isArchivedBefore)
  157. return chatIsArchived
  158. }
  159. public func blockContact() {
  160. context.blockContact(id: contact.id)
  161. }
  162. public func unblockContact() {
  163. context.unblockContact(id: contact.id)
  164. }
  165. }