From 8e46ff16d2f5bec95988e6079e3b4dbf25dbaf3b Mon Sep 17 00:00:00 2001 From: Adam Uncao Date: Mon, 15 Jul 2019 12:53:14 -0400 Subject: [PATCH 1/3] Added support for deleted messages request --- Rocket.Chat.xcodeproj/project.pbxproj | 5 ++ .../API/Clients/SubscriptionsClient.swift | 30 ++++++++++ .../Room/RoomDeletedMessagesRequest.swift | 55 +++++++++++++++++++ .../Chat/MessagesViewController.swift | 2 + .../Controllers/Chat/MessagesViewModel.swift | 11 ++++ .../Models/Subscription/Subscription.swift | 5 ++ 6 files changed, 108 insertions(+) create mode 100644 Rocket.Chat/API/Requests/Room/RoomDeletedMessagesRequest.swift diff --git a/Rocket.Chat.xcodeproj/project.pbxproj b/Rocket.Chat.xcodeproj/project.pbxproj index 0a4a63aea8..7d6b051f92 100644 --- a/Rocket.Chat.xcodeproj/project.pbxproj +++ b/Rocket.Chat.xcodeproj/project.pbxproj @@ -910,6 +910,7 @@ 99F8FAED20B66F210025FEEF /* ImageCoordinator.swift in Sources */ = {isa = PBXBuildFile; fileRef = 99F8FAEC20B66F210025FEEF /* ImageCoordinator.swift */; }; A0FFC1611E8A9D8D00A1B5EA /* TintedTextField.swift in Sources */ = {isa = PBXBuildFile; fileRef = A0FFC1601E8A9D8D00A1B5EA /* TintedTextField.swift */; }; AB2AC99226FB9C7C9DA45E94 /* Pods_Rocket_Chat_ShareExtension.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 6787D07A45177F339DB234DD /* Pods_Rocket_Chat_ShareExtension.framework */; }; + B3B47AC322DCCE13006E1EF7 /* RoomDeletedMessagesRequest.swift in Sources */ = {isa = PBXBuildFile; fileRef = B3B47AC222DCCE13006E1EF7 /* RoomDeletedMessagesRequest.swift */; }; B5893BF41F6C4A5F00365768 /* UserReviewManager.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5893BF31F6C4A5E00365768 /* UserReviewManager.swift */; }; B5893BF61F6C4B1D00365768 /* UserReviewManagerSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = B5893BF51F6C4B1D00365768 /* UserReviewManagerSpec.swift */; }; D10E9C1A1F643457007F1796 /* Channel.swift in Sources */ = {isa = PBXBuildFile; fileRef = D10E9C191F643457007F1796 /* Channel.swift */; }; @@ -1899,6 +1900,7 @@ 99F8FAEC20B66F210025FEEF /* ImageCoordinator.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ImageCoordinator.swift; sourceTree = ""; }; A0FFC1601E8A9D8D00A1B5EA /* TintedTextField.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = TintedTextField.swift; sourceTree = ""; }; AAC8D92081FF042E089F3063 /* Pods-Rocket.Chat.beta.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rocket.Chat.beta.xcconfig"; path = "Pods/Target Support Files/Pods-Rocket.Chat/Pods-Rocket.Chat.beta.xcconfig"; sourceTree = ""; }; + B3B47AC222DCCE13006E1EF7 /* RoomDeletedMessagesRequest.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = RoomDeletedMessagesRequest.swift; sourceTree = ""; }; B5893BF31F6C4A5E00365768 /* UserReviewManager.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = UserReviewManager.swift; sourceTree = ""; }; B5893BF51F6C4B1D00365768 /* UserReviewManagerSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserReviewManagerSpec.swift; sourceTree = ""; }; BCF38696E8EC385488688390 /* Pods-Rocket.Chat.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-Rocket.Chat.debug.xcconfig"; path = "Pods/Target Support Files/Pods-Rocket.Chat/Pods-Rocket.Chat.debug.xcconfig"; sourceTree = ""; }; @@ -3368,6 +3370,7 @@ 80235D1C1F740AAC00A56CA5 /* Room */ = { isa = PBXGroup; children = ( + B3B47AC222DCCE13006E1EF7 /* RoomDeletedMessagesRequest.swift */, 8062E32B20A1F8100044F407 /* RoomsRequest.swift */, 89AEB7F71F7D225D00112A09 /* RoomCreateRequest.swift */, 80A63C4E1F719F9600FE5AC4 /* RoomInfoRequest.swift */, @@ -4482,6 +4485,7 @@ developmentRegion = English; hasScannedForEncodings = 0; knownRegions = ( + English, en, Base, "pt-BR", @@ -5341,6 +5345,7 @@ 4162E1531D651A8800AAAE49 /* UserManager.swift in Sources */, 800FCD4C1F728EC800D9A692 /* ChannelInfoCellProtocol.swift in Sources */, 800E22841F8500A200DA84F1 /* MessagesListViewController.swift in Sources */, + B3B47AC322DCCE13006E1EF7 /* RoomDeletedMessagesRequest.swift in Sources */, 33D08E2720BD5EDC008D03EF /* NotThemeableViews.swift in Sources */, 41778EB920ED4C2C007F72F9 /* SubscriptionCellCondensed.swift in Sources */, 99805D7520C191BE00741B8E /* StyledTextField.swift in Sources */, diff --git a/Rocket.Chat/API/Clients/SubscriptionsClient.swift b/Rocket.Chat/API/Clients/SubscriptionsClient.swift index bf25368899..11dba11299 100644 --- a/Rocket.Chat/API/Clients/SubscriptionsClient.swift +++ b/Rocket.Chat/API/Clients/SubscriptionsClient.swift @@ -317,4 +317,34 @@ extension SubscriptionsClient { } } } + + func loadDeletedMessages(subscription: Subscription, realm: Realm? = Realm.current, completion: (([String]) -> Void)? = nil) { + + let request = RoomDeletedMessagesRequest(roomId: subscription.rid, since: subscription.deletedMessagesLastUpdated) + let identifier = subscription.identifier ?? "" + api.fetch(request, completion: {response in + switch response { + case .resource(let resource): + realm?.execute({ realm in + let deletedIDs = resource.messages?.compactMap { $0 } ?? [] + + if let sub = realm.object(ofType: Subscription.self, forPrimaryKey: identifier) { + sub.deletedMessagesLastUpdated = Date() + + let toDelete = sub.messages?.filter({ message in + return deletedIDs.contains(message.identifier ?? "") + }) + + if let toDelete = toDelete { + realm.delete(toDelete) + } + completion?(deletedIDs) + } + completion?([]) + }) + case .error: + completion?([]) + } + }) + } } diff --git a/Rocket.Chat/API/Requests/Room/RoomDeletedMessagesRequest.swift b/Rocket.Chat/API/Requests/Room/RoomDeletedMessagesRequest.swift new file mode 100644 index 0000000000..10442e6cf7 --- /dev/null +++ b/Rocket.Chat/API/Requests/Room/RoomDeletedMessagesRequest.swift @@ -0,0 +1,55 @@ +// +// RoomDeletedMessagesRequest.swift +// InfinityOne +// +// Created by Adam Uncao on 2019-07-12. +// Copyright © 2019 E-MetroTel. All rights reserved. +// + +import SwiftyJSON + +struct RoomDeletedMessagesRequest: APIRequest { + typealias APIResourceType = RoomDeletedMessagesResource + + let path = "/api/v1/chat.getDeletedMessages" + let requiredVersion = Version(1,1,0) + + var query: String? + let roomId: String? + let since: Date? + + init(roomId: String, since: Date) { + self.roomId = roomId + self.since = since + + let dateFormatter = ISO8601DateFormatter() + let dateString = dateFormatter.string(from: since) + + if let encodedString = dateString.addingPercentEncoding(withAllowedCharacters: .urlQueryAllowed) { + self.query = "roomId=\(roomId)&since=\(encodedString)" + } + } +} + +final class RoomDeletedMessagesResource: APIResource { + var messages: [String?]? { + return raw?["messages"].arrayValue.map { + if let removedMsg = $0.dictionaryObject, let msgId = removedMsg["_id"] as? String { + return msgId + } + return nil + } + } + + var count: Int? { + return raw?["count"].int + } + + var offset: Int? { + return raw?["offset"].int + } + + var total: Int? { + return raw?["total"].int + } +} diff --git a/Rocket.Chat/Controllers/Chat/MessagesViewController.swift b/Rocket.Chat/Controllers/Chat/MessagesViewController.swift index 2c45cec6a5..a3a746d4b2 100644 --- a/Rocket.Chat/Controllers/Chat/MessagesViewController.swift +++ b/Rocket.Chat/Controllers/Chat/MessagesViewController.swift @@ -743,6 +743,8 @@ extension MessagesViewController: SocketConnectionHandler { if state == .connected { viewModel.requestingData = .none + viewModel.fetchDeletedMessages() + if viewModel.threadIdentifier != nil { viewModel.fetchThreadMessages(from: nil) } else { diff --git a/Rocket.Chat/Controllers/Chat/MessagesViewModel.swift b/Rocket.Chat/Controllers/Chat/MessagesViewModel.swift index aa1eee1b58..f5394ca485 100644 --- a/Rocket.Chat/Controllers/Chat/MessagesViewModel.swift +++ b/Rocket.Chat/Controllers/Chat/MessagesViewModel.swift @@ -89,6 +89,7 @@ final class MessagesViewModel { }) fetchMessages(from: nil) + fetchDeletedMessages() } } @@ -648,6 +649,16 @@ final class MessagesViewModel { } } + func fetchDeletedMessages() { + guard let subscription = self.subscription, + let client = API.current()?.client(SubscriptionsClient.self) else { + return + } + client.loadDeletedMessages(subscription: subscription) { _ in + self.updateData() + } + } + // MARK: Data Manipulation /** diff --git a/Rocket.Chat/Models/Subscription/Subscription.swift b/Rocket.Chat/Models/Subscription/Subscription.swift index 2aad8f4ac3..37bc913deb 100644 --- a/Rocket.Chat/Models/Subscription/Subscription.swift +++ b/Rocket.Chat/Models/Subscription/Subscription.swift @@ -117,6 +117,11 @@ final class Subscription: BaseModel { let usersRoles = List() // MARK: Internal + + //Indicates when deleted messages were last updated. + // On new subscription objects our messages are up to date. + @objc dynamic var deletedMessagesLastUpdated: Date = Date() + @objc dynamic var privateOtherUserStatus: String? var otherUserStatus: UserStatus? { if let privateOtherUserStatus = privateOtherUserStatus { From cf1db47185c40a50736f53fdce8ef2e9e49ad498 Mon Sep 17 00:00:00 2001 From: Adam Uncao Date: Mon, 15 Jul 2019 13:28:44 -0400 Subject: [PATCH 2/3] Updated file header --- .../API/Requests/Room/RoomDeletedMessagesRequest.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Rocket.Chat/API/Requests/Room/RoomDeletedMessagesRequest.swift b/Rocket.Chat/API/Requests/Room/RoomDeletedMessagesRequest.swift index 10442e6cf7..9fe6cb6713 100644 --- a/Rocket.Chat/API/Requests/Room/RoomDeletedMessagesRequest.swift +++ b/Rocket.Chat/API/Requests/Room/RoomDeletedMessagesRequest.swift @@ -1,9 +1,9 @@ // // RoomDeletedMessagesRequest.swift -// InfinityOne +// Rocket.Chat // -// Created by Adam Uncao on 2019-07-12. -// Copyright © 2019 E-MetroTel. All rights reserved. +// Created by Luís Machado on 29/03/2019. +// Copyright © 2019 Rocket.Chat. All rights reserved. // import SwiftyJSON From f081eec32a1ee56adf45bee32d0f6d692b8db31d Mon Sep 17 00:00:00 2001 From: Adam Uncao Date: Mon, 15 Jul 2019 13:49:52 -0400 Subject: [PATCH 3/3] Fixes file lengths and request version --- Rocket.Chat/API/Clients/SubscriptionsClient.swift | 7 +++++-- .../API/Requests/Room/RoomDeletedMessagesRequest.swift | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/Rocket.Chat/API/Clients/SubscriptionsClient.swift b/Rocket.Chat/API/Clients/SubscriptionsClient.swift index 11dba11299..fc2ba7b209 100644 --- a/Rocket.Chat/API/Clients/SubscriptionsClient.swift +++ b/Rocket.Chat/API/Clients/SubscriptionsClient.swift @@ -318,9 +318,12 @@ extension SubscriptionsClient { } } - func loadDeletedMessages(subscription: Subscription, realm: Realm? = Realm.current, completion: (([String]) -> Void)? = nil) { + func loadDeletedMessages(subscription: Subscription, + realm: Realm? = Realm.current, + completion: (([String]) -> Void)? = nil) { - let request = RoomDeletedMessagesRequest(roomId: subscription.rid, since: subscription.deletedMessagesLastUpdated) + let sinceDate = subscription.deletedMessagesLastUpdated + let request = RoomDeletedMessagesRequest(roomId: subscription.rid, since: sinceDate) let identifier = subscription.identifier ?? "" api.fetch(request, completion: {response in switch response { diff --git a/Rocket.Chat/API/Requests/Room/RoomDeletedMessagesRequest.swift b/Rocket.Chat/API/Requests/Room/RoomDeletedMessagesRequest.swift index 9fe6cb6713..6e07e27212 100644 --- a/Rocket.Chat/API/Requests/Room/RoomDeletedMessagesRequest.swift +++ b/Rocket.Chat/API/Requests/Room/RoomDeletedMessagesRequest.swift @@ -12,7 +12,7 @@ struct RoomDeletedMessagesRequest: APIRequest { typealias APIResourceType = RoomDeletedMessagesResource let path = "/api/v1/chat.getDeletedMessages" - let requiredVersion = Version(1,1,0) + let requiredVersion = Version(0, 73, 0) var query: String? let roomId: String?