From c9d817e97551df0079f2279e040dd7376ffbd689 Mon Sep 17 00:00:00 2001 From: Mattermost Build Date: Fri, 2 Jun 2023 17:40:30 +0300 Subject: [PATCH] Native fetch users on attachments (#7382) (#7388) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * Native side of fetching users from attachments text and pretext * iOS native * Address feedback (cherry picked from commit e3658245679c8fba04652ef67ed27262f3626bce) Co-authored-by: Daniel Espino GarcĂ­a --- .../helpers/push_notification/Post.kt | 33 +++++++++++++++---- .../Sources/Gekidou/DataTypes/Post.swift | 6 ++-- .../Gekidou/Networking/Network+Posts.swift | 25 ++++++++++---- .../Gekidou/Storage/Database+Posts.swift | 8 ++++- 4 files changed, 55 insertions(+), 17 deletions(-) diff --git a/android/app/src/main/java/com/mattermost/helpers/push_notification/Post.kt b/android/app/src/main/java/com/mattermost/helpers/push_notification/Post.kt index c1694dcb1..6fb35c6ed 100644 --- a/android/app/src/main/java/com/mattermost/helpers/push_notification/Post.kt +++ b/android/app/src/main/java/com/mattermost/helpers/push_notification/Post.kt @@ -66,6 +66,20 @@ internal suspend fun PushNotificationDataRunnable.Companion.fetchPosts( } } + fun findNeededUsernames(text: String?) { + if (text == null) { + return + } + + val matchResults = regex.findAll(text) + matchResults.iterator().forEach { + val username = it.value.removePrefix("@") + if (!usernames.contains(username) && currentUsername != username && !specialMentions.contains(username)) { + usernames.add(username) + } + } + } + while (iterator.hasNextKey()) { val key = iterator.nextKey() val post = posts.getMap(key) @@ -73,17 +87,22 @@ internal suspend fun PushNotificationDataRunnable.Companion.fetchPosts( if (userId != null && userId != currentUserId && !userIdsAlreadyLoaded.contains(userId) && !userIds.contains(userId)) { userIds.add(userId) } + val message = post?.getString("message") - if (message != null) { - val matchResults = regex.findAll(message) - matchResults.iterator().forEach { - val username = it.value.removePrefix("@") - if (!usernames.contains(username) && currentUsername != username && !specialMentions.contains(username)) { - usernames.add(username) - } + findNeededUsernames(message) + val props = post?.getMap("props") + val attachments = props?.getArray("attachments") + if (attachments != null) { + for (i in 0 until attachments.size()) { + val attachment = attachments.getMap(i) + val pretext = attachment.getString("pretext") + val text = attachment.getString("text") + findNeededUsernames(pretext) + findNeededUsernames(text) } } + if (isCRTEnabled) { // Add root post as a thread val threadId = post?.getString("root_id") diff --git a/ios/Gekidou/Sources/Gekidou/DataTypes/Post.swift b/ios/Gekidou/Sources/Gekidou/DataTypes/Post.swift index 6fd655857..b96e8c987 100644 --- a/ios/Gekidou/Sources/Gekidou/DataTypes/Post.swift +++ b/ios/Gekidou/Sources/Gekidou/DataTypes/Post.swift @@ -14,7 +14,7 @@ public struct Post: Codable { let message: String let messageSource: String let type: String - let props: String + let props: [String: Any] let pendingPostId: String let metadata: String var prevPostId: String @@ -74,9 +74,9 @@ public struct Post: Codable { } if let propsData = try? values.decode([String:Any].self, forKey: .props) { - props = Database.default.json(from: propsData) ?? "{}" + props = propsData } else { - props = "{}" + props = [:] } } diff --git a/ios/Gekidou/Sources/Gekidou/Networking/Network+Posts.swift b/ios/Gekidou/Sources/Gekidou/Networking/Network+Posts.swift index 84f663e01..5001db4d7 100644 --- a/ios/Gekidou/Sources/Gekidou/Networking/Network+Posts.swift +++ b/ios/Gekidou/Sources/Gekidou/Networking/Network+Posts.swift @@ -85,11 +85,22 @@ extension Network { var userIdsToLoad: Set = Set() var usernamesToLoad: Set = Set() + func findNeededUsernames(text: String?) { + if let text = text { + for username in self.matchUsername(in: text) { + if username != currentUser.username && !threadParticipantUsernames.contains(username) && !usernamesToLoad.contains(username) { + usernamesToLoad.insert(username) + } + } + } + } + if let postsWithKeys = postResponse?.posts { let posts = Array(postsWithKeys.values) for post in posts { let authorId = post.userId let message = post.message + let attachments = post.props["attachments"] as? [[String: Any]] if isCRTEnabled && post.rootId.isEmpty { if threads == nil { @@ -118,12 +129,14 @@ extension Network { if (authorId != currentUser.id && !alreadyLoadedUserIds.contains(authorId) && !threadParticipantUserIds.contains(authorId) && !userIdsToLoad.contains(authorId)) { userIdsToLoad.insert(authorId) } - - if !message.isEmpty { - for username in self.matchUsername(in: message) { - if username != currentUser.username && !threadParticipantUsernames.contains(username) && !usernamesToLoad.contains(username) { - usernamesToLoad.insert(username) - } + + findNeededUsernames(text: message) + if let attachments = attachments { + for attachment in attachments { + let pretext = attachment["pretext"] as? String + let text = attachment["text"] as? String + findNeededUsernames(text: pretext) + findNeededUsernames(text: text) } } } diff --git a/ios/Gekidou/Sources/Gekidou/Storage/Database+Posts.swift b/ios/Gekidou/Sources/Gekidou/Storage/Database+Posts.swift index cce0a2f73..4d3b024b2 100644 --- a/ios/Gekidou/Sources/Gekidou/Storage/Database+Posts.swift +++ b/ios/Gekidou/Sources/Gekidou/Storage/Database+Posts.swift @@ -257,6 +257,12 @@ extension Database { for post in posts { var setter = [Setter]() let metadataSetters = createPostMetadataSetters(from: post) + let propsJSON = try? JSONSerialization.data(withJSONObject: post.props, options: []) + var propsString = "{}" + if let propsJSON = propsJSON { + propsString = String(data: propsJSON, encoding: String.Encoding.utf8) ?? "{}" + } + setter.append(id <- post.id) setter.append(createAt <- post.createAt) setter.append(updateAt <- post.updateAt) @@ -273,7 +279,7 @@ extension Database { setter.append(type <- post.type) setter.append(pendingPostId <- post.pendingPostId) setter.append(prevPostId <- post.prevPostId) - setter.append(props <- post.props) + setter.append(props <- propsString) setter.append(statusCol <- "created") let postSetter = PostSetters(