WebConversationsResponse.swift 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. // _____ _
  2. // |_ _| |_ _ _ ___ ___ _ __ __ _
  3. // | | | ' \| '_/ -_) -_) ' \/ _` |_
  4. // |_| |_||_|_| \___\___|_|_|_\__,_(_)
  5. //
  6. // Threema iOS Client
  7. // Copyright (c) 2018-2020 Threema GmbH
  8. //
  9. // This program is free software: you can redistribute it and/or modify
  10. // it under the terms of the GNU Affero General Public License, version 3,
  11. // as published by the Free Software Foundation.
  12. //
  13. // This program is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  16. // GNU Affero General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Affero General Public License
  19. // along with this program. If not, see <https://www.gnu.org/licenses/>.
  20. import Foundation
  21. class WebConversationsResponse: WebAbstractMessage {
  22. init(requestId: String?, conversationRequest: WebConversationsRequest?, session: WCSession) {
  23. var conversationArray = Array<[AnyHashable:Any]>();
  24. let entityManager = EntityManager()
  25. let allConversations = entityManager.entityFetcher.allConversationsSorted() as? [Conversation]
  26. var index:Int = 1
  27. for conver in allConversations! {
  28. if !conver.isGroup() && conver.contact == nil {
  29. // empty contact in a single conversation, do not send to web
  30. } else {
  31. let webConversation = WebConversation.init(conversation: conver, index: index, request: conversationRequest, addAvatar: index < 16 ? true : false, entityManager: entityManager, session: session)
  32. conversationArray.append(webConversation.objectDict())
  33. index = index + 1
  34. }
  35. }
  36. let tmpAck = requestId != nil ? WebAbstractMessageAcknowledgement.init(requestId, true, nil) : nil
  37. super.init(messageType: "response", messageSubType: "conversations", requestId: nil, ack: tmpAck, args: nil, data: conversationArray)
  38. }
  39. }
  40. struct WebConversation {
  41. var type: String
  42. var id: String
  43. var position: Int
  44. var messageCount: Int
  45. var unreadCount: Int
  46. var latestMessage: [AnyHashable: Any?]?
  47. var receiver: [AnyHashable: Any?]?
  48. var avatar: Data?
  49. var notifications: WebNotificationSettings?
  50. var isStarred: Bool?
  51. init(conversation: Conversation, index: Int, request: WebConversationsRequest?, addAvatar: Bool, entityManager: EntityManager, session: WCSession) {
  52. if conversation.isGroup() {
  53. type = "group"
  54. id = conversation.groupId.hexEncodedString()
  55. if let groupProxy = GroupProxy.init(for: conversation, entityManager: entityManager) {
  56. let group = WebGroup.init(group: groupProxy)
  57. receiver = group.objectDict()
  58. }
  59. } else {
  60. type = "contact"
  61. id = conversation.contact.identity
  62. let contact = WebContact.init(conversation.contact)
  63. receiver = contact.objectDict()
  64. }
  65. position = index
  66. messageCount = conversation.messages.count
  67. unreadCount = conversation.unreadMessageCount as! Int
  68. if conversation.lastMessage != nil && conversation.lastMessage.conversation != nil {
  69. let latestMessageObject = WebMessageObject.init(message: conversation.lastMessage, conversation: conversation, forConversationsRequest: true, session: session)
  70. latestMessage = latestMessageObject.objectDict()
  71. }
  72. let maxSize = request != nil ? request!.maxSize : 48
  73. let quality = request != nil ? 0.75 : 0.6
  74. if let avatarImage = AvatarMaker.shared().avatar(for: conversation, size: CGFloat(maxSize), masked: false, scaled: false) {
  75. avatar = avatarImage.jpegData(compressionQuality:CGFloat(quality))
  76. }
  77. if let pushSetting = PushSetting.find(for: conversation) {
  78. notifications = WebNotificationSettings.init(pushSetting: pushSetting)
  79. }
  80. isStarred = conversation.marked.boolValue
  81. }
  82. init(deletedConversation: Conversation, contact: Contact?) {
  83. if deletedConversation.isGroup() {
  84. type = "group"
  85. id = deletedConversation.groupId.hexEncodedString()
  86. } else {
  87. type = "contact"
  88. if deletedConversation.contact != nil {
  89. id = deletedConversation.contact.identity
  90. }
  91. else if contact != nil {
  92. id = contact!.identity
  93. }
  94. else {
  95. id = ""
  96. }
  97. }
  98. position = 0
  99. messageCount = 0
  100. unreadCount = 0
  101. }
  102. func objectDict() -> [String: Any] {
  103. var objectDict:[String: Any] = ["type": type, "id": id, "position": position, "messageCount": messageCount, "unreadCount": unreadCount]
  104. if latestMessage != nil {
  105. objectDict.updateValue(latestMessage!, forKey: "latestMessage")
  106. }
  107. if receiver != nil {
  108. objectDict.updateValue(receiver!, forKey: "receiver")
  109. }
  110. if avatar != nil {
  111. objectDict.updateValue(avatar!, forKey: "avatar")
  112. }
  113. if notifications != nil {
  114. objectDict.updateValue(notifications!.objectDict(), forKey: "notifications")
  115. }
  116. if isStarred != nil {
  117. objectDict.updateValue(isStarred!, forKey: "isStarred")
  118. }
  119. return objectDict
  120. }
  121. }
  122. struct WebNotificationSettings {
  123. var sound: WebNotificationSoundSetting
  124. var dnd: WebNotificationDndSetting
  125. init(pushSetting: PushSetting) {
  126. sound = WebNotificationSoundSetting.init(pushSetting: pushSetting)
  127. dnd = WebNotificationDndSetting.init(pushSetting: pushSetting)
  128. }
  129. func objectDict() -> [String: Any] {
  130. return ["sound": sound.objectDict(), "dnd": dnd.objectDict()]
  131. }
  132. }
  133. struct WebNotificationSoundSetting {
  134. var mode: String
  135. init(pushSetting: PushSetting) {
  136. mode = pushSetting.silent ? "muted" : "default"
  137. }
  138. func objectDict() -> [String: Any] {
  139. return ["mode": mode]
  140. }
  141. }
  142. struct WebNotificationDndSetting {
  143. var mode: String
  144. var until: Int
  145. var mention: Bool
  146. init(pushSetting: PushSetting) {
  147. until = 0
  148. mode = "off"
  149. if pushSetting.type == .off {
  150. mode = "on"
  151. }
  152. else if pushSetting.type == .offPeriod {
  153. mode = "until"
  154. until = Int(pushSetting.periodOffTillDate.timeIntervalSince1970)
  155. }
  156. mention = pushSetting.mentions
  157. }
  158. func objectDict() -> [String: Any] {
  159. var objectDict:[String: Any] = ["mode": mode]
  160. if mode == "until" {
  161. objectDict.updateValue(until, forKey: "until")
  162. }
  163. if mention == true {
  164. objectDict.updateValue(mention, forKey: "mentionOnly")
  165. }
  166. return objectDict
  167. }
  168. }
  169. extension Data
  170. {
  171. func toString() -> String
  172. {
  173. return String(data: self, encoding: .utf8)!
  174. }
  175. }