From b4af9d16d599e4d1c1539c53cab3cf26bc07087c Mon Sep 17 00:00:00 2001 From: Niels Andriesse Date: Tue, 15 Oct 2019 10:29:41 +1100 Subject: [PATCH] Refactor --- Signal/src/AppDelegate.m | 2 +- .../Loki/MentionCandidateSelectionView.swift | 2 +- Signal/src/Loki/NewPublicChatVC.swift | 4 +- .../src/Loki/Utilities/MentionUtilities.swift | 8 +- .../ConversationView/Cells/OWSMessageCell.m | 14 ++- .../Cells/OWSQuotedMessageView.m | 6 +- .../ConversationInputToolbar.m | 10 +- .../ConversationView/ConversationViewItem.m | 16 +-- .../environment/VersionMigrations.m | 4 +- SignalMessaging/profiles/OWSProfileManager.m | 8 +- SignalServiceKit/src/Loki/API/LokiAPI.swift | 8 +- .../LokiChannelInfo.swift | 0 .../LokiPublicChat.swift} | 10 +- .../LokiPublicChatAPI.swift} | 108 +++++++++--------- .../API/Public Chat/LokiPublicChatInfo.swift | 4 + .../LokiPublicChatManager.swift | 30 ++--- .../LokiPublicChatMessage.swift} | 10 +- .../LokiRSSFeed.swift | 0 .../PublicChatPoller.swift} | 18 +-- .../Loki/Database/LokiDatabaseUtilities.swift | 34 +++--- .../Loki/Utilities/DisplayNameUtilities.swift | 6 +- .../src/Messages/Interactions/TSMessage.h | 4 +- .../src/Messages/OWSMessageSender.m | 18 +-- 23 files changed, 168 insertions(+), 156 deletions(-) rename SignalServiceKit/src/Loki/API/{Group Chat => Public Chat}/LokiChannelInfo.swift (100%) rename SignalServiceKit/src/Loki/API/{Group Chat/LokiGroupChat.swift => Public Chat/LokiPublicChat.swift} (77%) rename SignalServiceKit/src/Loki/API/{Group Chat/LokiGroupChatAPI.swift => Public Chat/LokiPublicChatAPI.swift} (70%) create mode 100644 SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatInfo.swift rename SignalServiceKit/src/Loki/API/{Group Chat => Public Chat}/LokiPublicChatManager.swift (82%) rename SignalServiceKit/src/Loki/API/{Group Chat/LokiGroupMessage.swift => Public Chat/LokiPublicChatMessage.swift} (91%) rename SignalServiceKit/src/Loki/API/{Group Chat => Public Chat}/LokiRSSFeed.swift (100%) rename SignalServiceKit/src/Loki/API/{Group Chat/GroupChatPoller.swift => Public Chat/PublicChatPoller.swift} (91%) diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index ba5626c2d..3afa2da86 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -1537,7 +1537,7 @@ static NSTimeInterval launchStartedAt; - (void)createGroupChatsIfNeeded { // Setup our default public chats - for (LKGroupChat *chat in LKGroupChat.defaultChats) { + for (LKPublicChat *chat in LKPublicChat.defaultChats) { NSString *userDefaultsKey = [@"isGroupChatSetUp." stringByAppendingString:chat.id]; BOOL isChatSetUp = [NSUserDefaults.standardUserDefaults boolForKey:userDefaultsKey]; if (!isChatSetUp || !chat.isDeletable) { diff --git a/Signal/src/Loki/MentionCandidateSelectionView.swift b/Signal/src/Loki/MentionCandidateSelectionView.swift index b6c1798ed..1f2f16c4d 100644 --- a/Signal/src/Loki/MentionCandidateSelectionView.swift +++ b/Signal/src/Loki/MentionCandidateSelectionView.swift @@ -131,7 +131,7 @@ private extension MentionCandidateSelectionView { let profilePicture = OWSContactAvatarBuilder(signalId: mentionCandidate.hexEncodedPublicKey, colorName: .blue, diameter: 36).build() profilePictureImageView.image = profilePicture if let publicChatServer = publicChatServer, let publicChatServerID = publicChatServerID { - let isUserModerator = LokiGroupChatAPI.isUserModerator(mentionCandidate.hexEncodedPublicKey, for: publicChatServerID, on: publicChatServer) + let isUserModerator = LokiPublicChatAPI.isUserModerator(mentionCandidate.hexEncodedPublicKey, for: publicChatServerID, on: publicChatServer) moderatorIconImageView.isHidden = !isUserModerator } else { moderatorIconImageView.isHidden = true diff --git a/Signal/src/Loki/NewPublicChatVC.swift b/Signal/src/Loki/NewPublicChatVC.swift index 2d0e95260..205c18a65 100644 --- a/Signal/src/Loki/NewPublicChatVC.swift +++ b/Signal/src/Loki/NewPublicChatVC.swift @@ -88,8 +88,8 @@ final class NewPublicChatVC : OWSViewController { let displayName = OWSProfileManager.shared().localProfileName() LokiPublicChatManager.shared.addChat(server: urlAsString, channel: channelID) .done(on: .main) { [weak self] _ in - let _ = LokiGroupChatAPI.getMessages(for: channelID, on: urlAsString) - let _ = LokiGroupChatAPI.setDisplayName(to: displayName, on: urlAsString) + let _ = LokiPublicChatAPI.getMessages(for: channelID, on: urlAsString) + let _ = LokiPublicChatAPI.setDisplayName(to: displayName, on: urlAsString) self?.presentingViewController!.dismiss(animated: true, completion: nil) } .catch(on: .main) { [weak self] _ in diff --git a/Signal/src/Loki/Utilities/MentionUtilities.swift b/Signal/src/Loki/Utilities/MentionUtilities.swift index 3268a045d..a2e72f31f 100644 --- a/Signal/src/Loki/Utilities/MentionUtilities.swift +++ b/Signal/src/Loki/Utilities/MentionUtilities.swift @@ -9,9 +9,9 @@ public final class MentionUtilities : NSObject { } @objc public static func highlightMentions(in string: String, isOutgoingMessage: Bool, threadID: String, attributes: [NSAttributedString.Key:Any]) -> NSAttributedString { - var groupChat: LokiGroupChat? + var publicChat: LokiPublicChat? OWSPrimaryStorage.shared().dbReadConnection.read { transaction in - groupChat = LokiDatabaseUtilities.getGroupChat(for: threadID, in: transaction) + publicChat = LokiDatabaseUtilities.getPublicChat(for: threadID, in: transaction) } var string = string let regex = try! NSRegularExpression(pattern: "@[0-9a-fA-F]*", options: []) @@ -26,8 +26,8 @@ public final class MentionUtilities : NSObject { if hexEncodedPublicKey == OWSIdentityManager.shared().identityKeyPair()!.hexEncodedPublicKey { userDisplayName = OWSProfileManager.shared().localProfileName() } else { - if let groupChat = groupChat { - userDisplayName = DisplayNameUtilities.getGroupChatDisplayName(for: hexEncodedPublicKey, in: groupChat.channel, on: groupChat.server) + if let publicChat = publicChat { + userDisplayName = DisplayNameUtilities.getPublicChatDisplayName(for: hexEncodedPublicKey, in: publicChat.channel, on: publicChat.server) } else { userDisplayName = DisplayNameUtilities.getPrivateChatDisplayName(for: hexEncodedPublicKey) } diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m index ecde97570..980db5544 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m @@ -299,14 +299,16 @@ NS_ASSUME_NONNULL_BEGIN [self.contentView addSubview:self.avatarView]; if (self.viewItem.isGroupThread && !self.viewItem.isRSSFeed) { - __block LKGroupChat *groupChat; + __block LKPublicChat *publicChat; [OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { - groupChat = [LKDatabaseUtilities getGroupChatForThreadID:self.viewItem.interaction.uniqueThreadId transaction: transaction]; + publicChat = [LKDatabaseUtilities getPublicChatForThreadID:self.viewItem.interaction.uniqueThreadId transaction: transaction]; }]; - BOOL isModerator = [LKGroupChatAPI isUserModerator:incomingMessage.authorId forGroup:groupChat.channel onServer:groupChat.server]; - UIImage *moderatorIcon = [UIImage imageNamed:@"Crown"]; - self.moderatorIconImageView.image = moderatorIcon; - self.moderatorIconImageView.hidden = !isModerator; + if (publicChat != nil) { + BOOL isModerator = [LKPublicChatAPI isUserModerator:incomingMessage.authorId forGroup:publicChat.channel onServer:publicChat.server]; + UIImage *moderatorIcon = [UIImage imageNamed:@"Crown"]; + self.moderatorIconImageView.image = moderatorIcon; + self.moderatorIconImageView.hidden = !isModerator; + } } [self.contentView addSubview:self.moderatorIconImageView]; diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSQuotedMessageView.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSQuotedMessageView.m index 680a1df7d..386fc4d0b 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSQuotedMessageView.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSQuotedMessageView.m @@ -554,9 +554,9 @@ const CGFloat kRemotelySourcedContentRowSpacing = 3; if (quotedAuthor == self.quotedMessage.authorId) { [OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { - LKGroupChat *groupChat = [LKDatabaseUtilities getGroupChatForThreadID:self.quotedMessage.threadId transaction:transaction]; - if (groupChat != nil) { - quotedAuthor = [LKDisplayNameUtilities getGroupChatDisplayNameFor:self.quotedMessage.authorId in:groupChat.channel on:groupChat.server using:transaction];; + LKPublicChat *publicChat = [LKDatabaseUtilities getPublicChatForThreadID:self.quotedMessage.threadId transaction:transaction]; + if (publicChat != nil) { + quotedAuthor = [LKDisplayNameUtilities getPublicChatDisplayNameFor:self.quotedMessage.authorId in:publicChat.channel on:publicChat.server using:transaction]; } else { quotedAuthor = [LKDisplayNameUtilities getPrivateChatDisplayNameFor:self.quotedMessage.authorId]; } diff --git a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m index 141f448df..c31d07915 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationInputToolbar.m @@ -1093,12 +1093,14 @@ const CGFloat kMaxTextViewHeight = 98; - (void)showMentionCandidateSelectionViewFor:(NSArray *)mentionCandidates in:(TSThread *)thread { - __block LKGroupChat *groupChat; + __block LKPublicChat *publicChat; [OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { - groupChat = [LKDatabaseUtilities getGroupChatForThreadID:thread.uniqueId transaction:transaction]; + publicChat = [LKDatabaseUtilities getPublicChatForThreadID:thread.uniqueId transaction:transaction]; }]; - self.mentionCandidateSelectionView.publicChatServer = groupChat.server; - [self.mentionCandidateSelectionView setPublicChatServerID:groupChat.channel]; + if (publicChat != nil) { + self.mentionCandidateSelectionView.publicChatServer = publicChat.server; + [self.mentionCandidateSelectionView setPublicChatServerID:publicChat.channel]; + } self.mentionCandidateSelectionView.mentionCandidates = mentionCandidates; self.mentionCandidateSelectionViewSizeConstraint.constant = 6 + MIN(mentionCandidates.count, 4) * 52; [self setNeedsLayout]; diff --git a/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m b/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m index cdc1ee68a..71ced588e 100644 --- a/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m +++ b/Signal/src/ViewControllers/ConversationView/ConversationViewItem.m @@ -1187,15 +1187,15 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) TSMessage *message = (TSMessage *)self.interaction; if (!message.isGroupChatMessage) return; - __block LKGroupChat *groupChat; + __block LKPublicChat *publicChat; [self.primaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { - groupChat = [LKDatabaseUtilities getGroupChatForThreadID:groupThread.uniqueId transaction: transaction]; + publicChat = [LKDatabaseUtilities getPublicChatForThreadID:groupThread.uniqueId transaction: transaction]; }]; - if (groupChat == nil) return; + if (publicChat == nil) return; // Delete the message BOOL isSentByUser = (interationType == OWSInteractionType_OutgoingMessage); - [[LKGroupChatAPI deleteMessageWithID:message.groupChatServerID forGroup:groupChat.channel onServer:groupChat.server isSentByUser:isSentByUser].catch(^(NSError *error) { + [[LKPublicChatAPI deleteMessageWithID:message.groupChatServerID forGroup:publicChat.channel onServer:publicChat.server isSentByUser:isSentByUser].catch(^(NSError *error) { // Roll back [self.interaction save]; }) retainUntilComplete]; @@ -1263,15 +1263,15 @@ NSString *NSStringForOWSMessageCellType(OWSMessageCellType cellType) if (!message.isGroupChatMessage) return false; // Ensure we have the details needed to contact the server - __block LKGroupChat *groupChat; + __block LKPublicChat *publicChat; [self.primaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { - groupChat = [LKDatabaseUtilities getGroupChatForThreadID:groupThread.uniqueId transaction: transaction]; + publicChat = [LKDatabaseUtilities getPublicChatForThreadID:groupThread.uniqueId transaction: transaction]; }]; - if (groupChat == nil) return false; + if (publicChat == nil) return false; // Only allow deletion on incoming messages if the user has moderation permission if (interationType == OWSInteractionType_IncomingMessage) { - BOOL isModerator = [LKGroupChatAPI isUserModerator:self.userHexEncodedPublicKey forGroup:groupChat.channel onServer:groupChat.server]; + BOOL isModerator = [LKPublicChatAPI isUserModerator:self.userHexEncodedPublicKey forGroup:publicChat.channel onServer:publicChat.server]; if (!isModerator) return false; } diff --git a/SignalMessaging/environment/VersionMigrations.m b/SignalMessaging/environment/VersionMigrations.m index dec2b762c..a195c1444 100644 --- a/SignalMessaging/environment/VersionMigrations.m +++ b/SignalMessaging/environment/VersionMigrations.m @@ -173,10 +173,10 @@ NS_ASSUME_NONNULL_BEGIN + (void)updatePublicChatMapping { [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction * _Nonnull transaction) { - for (LKGroupChat *chat in LKGroupChat.defaultChats) { + for (LKPublicChat *chat in LKPublicChat.defaultChats) { TSGroupThread *thread = [TSGroupThread threadWithGroupId:chat.idAsData transaction:transaction]; if (thread != nil) { - [LKDatabaseUtilities setGroupChat:chat threadID:thread.uniqueId transaction:transaction]; + [LKDatabaseUtilities setPublicChat:chat threadID:thread.uniqueId transaction:transaction]; } } }]; diff --git a/SignalMessaging/profiles/OWSProfileManager.m b/SignalMessaging/profiles/OWSProfileManager.m index c9edb900f..9b26be0b2 100644 --- a/SignalMessaging/profiles/OWSProfileManager.m +++ b/SignalMessaging/profiles/OWSProfileManager.m @@ -535,15 +535,15 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error); OWSAssertDebug(successBlock); OWSAssertDebug(failureBlock); - __block NSDictionary *groupChats; + __block NSDictionary *publicChats; [SSKEnvironment.shared.primaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { - groupChats = [LKDatabaseUtilities getAllGroupChats:transaction]; + publicChats = [LKDatabaseUtilities getAllPublicChats:transaction]; }]; - NSSet *servers = [NSSet setWithArray:[groupChats.allValues map:^NSString *(LKGroupChat *groupChat) { return groupChat.server; }]]; + NSSet *servers = [NSSet setWithArray:[publicChats.allValues map:^NSString *(LKPublicChat *publicChat) { return publicChat.server; }]]; for (NSString *server in servers) { - [[LKGroupChatAPI setDisplayName:localProfileName on:server] retainUntilComplete]; + [[LKPublicChatAPI setDisplayName:localProfileName on:server] retainUntilComplete]; } successBlock(); diff --git a/SignalServiceKit/src/Loki/API/LokiAPI.swift b/SignalServiceKit/src/Loki/API/LokiAPI.swift index cb654cfd8..f022d475f 100644 --- a/SignalServiceKit/src/Loki/API/LokiAPI.swift +++ b/SignalServiceKit/src/Loki/API/LokiAPI.swift @@ -309,15 +309,15 @@ public final class LokiAPI : NSObject { guard let cache = userHexEncodedPublicKeyCache[threadID] else { return [] } var candidates: [Mention] = [] // Gather candidates - var groupChat: LokiGroupChat? + var publicChat: LokiPublicChat? storage.dbReadConnection.read { transaction in - groupChat = LokiDatabaseUtilities.getGroupChat(for: threadID, in: transaction) + publicChat = LokiDatabaseUtilities.getPublicChat(for: threadID, in: transaction) } storage.dbReadConnection.read { transaction in candidates = cache.flatMap { hexEncodedPublicKey in let uncheckedDisplayName: String? - if let groupChat = groupChat { - uncheckedDisplayName = DisplayNameUtilities.getGroupChatDisplayName(for: hexEncodedPublicKey, in: groupChat.channel, on: groupChat.server) + if let publicChat = publicChat { + uncheckedDisplayName = DisplayNameUtilities.getPublicChatDisplayName(for: hexEncodedPublicKey, in: publicChat.channel, on: publicChat.server) } else { uncheckedDisplayName = DisplayNameUtilities.getPrivateChatDisplayName(for: hexEncodedPublicKey) } diff --git a/SignalServiceKit/src/Loki/API/Group Chat/LokiChannelInfo.swift b/SignalServiceKit/src/Loki/API/Public Chat/LokiChannelInfo.swift similarity index 100% rename from SignalServiceKit/src/Loki/API/Group Chat/LokiChannelInfo.swift rename to SignalServiceKit/src/Loki/API/Public Chat/LokiChannelInfo.swift diff --git a/SignalServiceKit/src/Loki/API/Group Chat/LokiGroupChat.swift b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChat.swift similarity index 77% rename from SignalServiceKit/src/Loki/API/Group Chat/LokiGroupChat.swift rename to SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChat.swift index 4d565b80d..7720dae79 100644 --- a/SignalServiceKit/src/Loki/API/Group Chat/LokiGroupChat.swift +++ b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChat.swift @@ -1,6 +1,6 @@ -@objc(LKGroupChat) -public final class LokiGroupChat : NSObject, NSCoding { +@objc(LKPublicChat) +public final class LokiPublicChat : NSObject, NSCoding { @objc public let id: String @objc public let idAsData: Data @objc public let channel: UInt64 @@ -8,11 +8,11 @@ public final class LokiGroupChat : NSObject, NSCoding { @objc public let displayName: String @objc public let isDeletable: Bool - @objc public static var defaultChats: [LokiGroupChat] { - var chats = [LokiGroupChat(channel: UInt64(1), server: "https://chat.lokinet.org", displayName: NSLocalizedString("Loki Public Chat", comment: ""), isDeletable: true)!] + @objc public static var defaultChats: [LokiPublicChat] { + var chats = [LokiPublicChat(channel: UInt64(1), server: "https://chat.lokinet.org", displayName: NSLocalizedString("Loki Public Chat", comment: ""), isDeletable: true)!] #if DEBUG - chats.append(LokiGroupChat(channel: UInt64(1), server: "https://chat-dev.lokinet.org", displayName: "Loki Dev Chat", isDeletable: true)!) + chats.append(LokiPublicChat(channel: UInt64(1), server: "https://chat-dev.lokinet.org", displayName: "Loki Dev Chat", isDeletable: true)!) #endif return chats diff --git a/SignalServiceKit/src/Loki/API/Group Chat/LokiGroupChatAPI.swift b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatAPI.swift similarity index 70% rename from SignalServiceKit/src/Loki/API/Group Chat/LokiGroupChatAPI.swift rename to SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatAPI.swift index 6c1b77ae6..f258cd8f7 100644 --- a/SignalServiceKit/src/Loki/API/Group Chat/LokiGroupChatAPI.swift +++ b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatAPI.swift @@ -1,7 +1,7 @@ import PromiseKit -@objc(LKGroupChatAPI) -public final class LokiGroupChatAPI : LokiDotNetAPI { +@objc(LKPublicChatAPI) +public final class LokiPublicChatAPI : LokiDotNetAPI { private static var moderators: [String:[UInt64:Set]] = [:] // Server URL to (channel ID to set of moderator IDs) // MARK: Settings @@ -9,8 +9,8 @@ public final class LokiGroupChatAPI : LokiDotNetAPI { private static let maxRetryCount: UInt = 8 // MARK: Public Chat - @objc public static let publicChatMessageType = "network.loki.messenger.publicChat" @objc private static let channelInfoType = "net.patter-app.settings" + @objc public static let publicChatMessageType = "network.loki.messenger.publicChat" // MARK: Convenience private static var userDisplayName: String { @@ -18,9 +18,9 @@ public final class LokiGroupChatAPI : LokiDotNetAPI { } // MARK: Database - override internal class var authTokenCollection: String { "LokiGroupChatAuthTokenCollection" } - private static let lastMessageServerIDCollection = "LokiGroupChatLastMessageServerIDCollection" - private static let lastDeletionServerIDCollection = "LokiGroupChatLastDeletionServerIDCollection" + override internal class var authTokenCollection: String { "LokiGroupChatAuthTokenCollection" } // Should ideally be LokiPublicChatAuthTokenCollection + private static let lastMessageServerIDCollection = "LokiGroupChatLastMessageServerIDCollection" // Should ideally be LokiPublicChatLastMessageServerIDCollection + private static let lastDeletionServerIDCollection = "LokiGroupChatLastDeletionServerIDCollection" // Should ideally be LokiPublicChatLastDeletionServerIDCollection private static func getLastMessageServerID(for group: UInt64, on server: String) -> UInt? { var result: UInt? = nil @@ -63,19 +63,19 @@ public final class LokiGroupChatAPI : LokiDotNetAPI { } // MARK: Public API - public static func getMessages(for group: UInt64, on server: String) -> Promise<[LokiGroupMessage]> { - print("[Loki] Getting messages for group chat with ID: \(group) on server: \(server).") + public static func getMessages(for channel: UInt64, on server: String) -> Promise<[LokiPublicChatMessage]> { + print("[Loki] Getting messages for public chat channel with ID: \(channel) on server: \(server).") var queryParameters = "include_annotations=1" - if let lastMessageServerID = getLastMessageServerID(for: group, on: server) { + if let lastMessageServerID = getLastMessageServerID(for: channel, on: server) { queryParameters += "&since_id=\(lastMessageServerID)" } else { queryParameters += "&count=-\(fallbackBatchCount)" } - let url = URL(string: "\(server)/channels/\(group)/messages?\(queryParameters)")! + let url = URL(string: "\(server)/channels/\(channel)/messages?\(queryParameters)")! let request = TSRequest(url: url) return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.map { rawResponse in guard let json = rawResponse as? JSON, let rawMessages = json["data"] as? [JSON] else { - print("[Loki] Couldn't parse messages for group chat with ID: \(group) on server: \(server) from: \(rawResponse).") + print("[Loki] Couldn't parse messages for public chat channel with ID: \(channel) on server: \(server) from: \(rawResponse).") throw Error.parsingFailed } return rawMessages.flatMap { message in @@ -85,23 +85,23 @@ public final class LokiGroupChatAPI : LokiDotNetAPI { let serverID = message["id"] as? UInt64, let hexEncodedSignatureData = value["sig"] as? String, let signatureVersion = value["sigver"] as? UInt64, let body = message["text"] as? String, let user = message["user"] as? JSON, let hexEncodedPublicKey = user["username"] as? String, let timestamp = value["timestamp"] as? UInt64 else { - print("[Loki] Couldn't parse message for group chat with ID: \(group) on server: \(server) from: \(message).") + print("[Loki] Couldn't parse message for public chat channel with ID: \(channel) on server: \(server) from: \(message).") return nil } let displayName = user["name"] as? String ?? NSLocalizedString("Anonymous", comment: "") - let lastMessageServerID = getLastMessageServerID(for: group, on: server) - if serverID > (lastMessageServerID ?? 0) { setLastMessageServerID(for: group, on: server, to: serverID) } - let quote: LokiGroupMessage.Quote? + let lastMessageServerID = getLastMessageServerID(for: channel, on: server) + if serverID > (lastMessageServerID ?? 0) { setLastMessageServerID(for: channel, on: server, to: serverID) } + let quote: LokiPublicChatMessage.Quote? if let quoteAsJSON = value["quote"] as? JSON, let quotedMessageTimestamp = quoteAsJSON["id"] as? UInt64, let quoteeHexEncodedPublicKey = quoteAsJSON["author"] as? String, let quotedMessageBody = quoteAsJSON["text"] as? String { let quotedMessageServerID = message["reply_to"] as? UInt64 - quote = LokiGroupMessage.Quote(quotedMessageTimestamp: quotedMessageTimestamp, quoteeHexEncodedPublicKey: quoteeHexEncodedPublicKey, quotedMessageBody: quotedMessageBody, quotedMessageServerID: quotedMessageServerID) + quote = LokiPublicChatMessage.Quote(quotedMessageTimestamp: quotedMessageTimestamp, quoteeHexEncodedPublicKey: quoteeHexEncodedPublicKey, quotedMessageBody: quotedMessageBody, quotedMessageServerID: quotedMessageServerID) } else { quote = nil } - let signature = LokiGroupMessage.Signature(data: Data(hex: hexEncodedSignatureData), version: signatureVersion) - let result = LokiGroupMessage(serverID: serverID, hexEncodedPublicKey: hexEncodedPublicKey, displayName: displayName, body: body, type: publicChatMessageType, timestamp: timestamp, quote: quote, signature: signature) + let signature = LokiPublicChatMessage.Signature(data: Data(hex: hexEncodedSignatureData), version: signatureVersion) + let result = LokiPublicChatMessage(serverID: serverID, hexEncodedPublicKey: hexEncodedPublicKey, displayName: displayName, body: body, type: publicChatMessageType, timestamp: timestamp, quote: quote, signature: signature) guard result.hasValidSignature() else { - print("[Loki] Ignoring group chat message with invalid signature.") + print("[Loki] Ignoring public chat message with invalid signature.") return nil } return result @@ -109,11 +109,11 @@ public final class LokiGroupChatAPI : LokiDotNetAPI { } } - public static func sendMessage(_ message: LokiGroupMessage, to group: UInt64, on server: String) -> Promise { + public static func sendMessage(_ message: LokiPublicChatMessage, to channel: UInt64, on server: String) -> Promise { guard let signedMessage = message.sign(with: userKeyPair.privateKey) else { return Promise(error: Error.signingFailed) } - return getAuthToken(for: server).then { token -> Promise in - print("[Loki] Sending message to group chat with ID: \(group) on server: \(server).") - let url = URL(string: "\(server)/channels/\(group)/messages")! + return getAuthToken(for: server).then { token -> Promise in + print("[Loki] Sending message to public chat channel with ID: \(channel) on server: \(server).") + let url = URL(string: "\(server)/channels/\(channel)/messages")! let parameters = signedMessage.toJSON() let request = TSRequest(url: url, method: "POST", parameters: parameters) request.allHTTPHeaderFields = [ "Content-Type" : "application/json", "Authorization" : "Bearer \(token)" ] @@ -124,13 +124,13 @@ public final class LokiGroupChatAPI : LokiDotNetAPI { dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ" guard let json = rawResponse as? JSON, let messageAsJSON = json["data"] as? JSON, let serverID = messageAsJSON["id"] as? UInt64, let body = messageAsJSON["text"] as? String, let dateAsString = messageAsJSON["created_at"] as? String, let date = dateFormatter.date(from: dateAsString) else { - print("[Loki] Couldn't parse message for group chat with ID: \(group) on server: \(server) from: \(rawResponse).") + print("[Loki] Couldn't parse message for public chat channel with ID: \(channel) on server: \(server) from: \(rawResponse).") throw Error.parsingFailed } let timestamp = UInt64(date.timeIntervalSince1970) * 1000 - return LokiGroupMessage(serverID: serverID, hexEncodedPublicKey: userHexEncodedPublicKey, displayName: displayName, body: body, type: publicChatMessageType, timestamp: timestamp, quote: signedMessage.quote, signature: signedMessage.signature) + return LokiPublicChatMessage(serverID: serverID, hexEncodedPublicKey: userHexEncodedPublicKey, displayName: displayName, body: body, type: publicChatMessageType, timestamp: timestamp, quote: signedMessage.quote, signature: signedMessage.signature) } - }.recover { error -> Promise in + }.recover { error -> Promise in if let error = error as? NetworkManagerError, error.statusCode == 401 { print("[Loki] Group chat auth token for: \(server) expired; dropping it.") storage.dbReadWriteConnection.removeObject(forKey: server, inCollection: authTokenCollection) @@ -139,44 +139,44 @@ public final class LokiGroupChatAPI : LokiDotNetAPI { }.retryingIfNeeded(maxRetryCount: maxRetryCount).map { message in Analytics.shared.track("Group Message Sent") return message - }.recover { error -> Promise in + }.recover { error -> Promise in Analytics.shared.track("Failed to Send Group Message") throw error } } - public static func getDeletedMessageServerIDs(for group: UInt64, on server: String) -> Promise<[UInt64]> { - print("[Loki] Getting deleted messages for group chat with ID: \(group) on server: \(server).") + public static func getDeletedMessageServerIDs(for channel: UInt64, on server: String) -> Promise<[UInt64]> { + print("[Loki] Getting deleted messages for public chat channel with ID: \(channel) on server: \(server).") let queryParameters: String - if let lastDeletionServerID = getLastDeletionServerID(for: group, on: server) { + if let lastDeletionServerID = getLastDeletionServerID(for: channel, on: server) { queryParameters = "since_id=\(lastDeletionServerID)" } else { queryParameters = "count=\(fallbackBatchCount)" } - let url = URL(string: "\(server)/loki/v1/channel/\(group)/deletes?\(queryParameters)")! + let url = URL(string: "\(server)/loki/v1/channel/\(channel)/deletes?\(queryParameters)")! let request = TSRequest(url: url) return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.map { rawResponse in guard let json = rawResponse as? JSON, let deletions = json["data"] as? [JSON] else { - print("[Loki] Couldn't parse deleted messages for group chat with ID: \(group) on server: \(server) from: \(rawResponse).") + print("[Loki] Couldn't parse deleted messages for public chat channel with ID: \(channel) on server: \(server) from: \(rawResponse).") throw Error.parsingFailed } return deletions.flatMap { deletion in guard let serverID = deletion["id"] as? UInt64, let messageServerID = deletion["message_id"] as? UInt64 else { - print("[Loki] Couldn't parse deleted message for group chat with ID: \(group) on server: \(server) from: \(deletion).") + print("[Loki] Couldn't parse deleted message for public chat channel with ID: \(channel) on server: \(server) from: \(deletion).") return nil } - let lastDeletionServerID = getLastDeletionServerID(for: group, on: server) - if serverID > (lastDeletionServerID ?? 0) { setLastDeletionServerID(for: group, on: server, to: serverID) } + let lastDeletionServerID = getLastDeletionServerID(for: channel, on: server) + if serverID > (lastDeletionServerID ?? 0) { setLastDeletionServerID(for: channel, on: server, to: serverID) } return messageServerID } } } - public static func deleteMessage(with messageID: UInt, for group: UInt64, on server: String, isSentByUser: Bool) -> Promise { + public static func deleteMessage(with messageID: UInt, for channel: UInt64, on server: String, isSentByUser: Bool) -> Promise { return getAuthToken(for: server).then { token -> Promise in let isModerationRequest = !isSentByUser - print("[Loki] Deleting message with ID: \(messageID) for group chat with ID: \(group) on server: \(server) (isModerationRequest = \(isModerationRequest)).") - let urlAsString = isSentByUser ? "\(server)/channels/\(group)/messages/\(messageID)" : "\(server)/loki/v1/moderation/message/\(messageID)" + print("[Loki] Deleting message with ID: \(messageID) for public chat channel with ID: \(channel) on server: \(server) (isModerationRequest = \(isModerationRequest)).") + let urlAsString = isSentByUser ? "\(server)/channels/\(channel)/messages/\(messageID)" : "\(server)/loki/v1/moderation/message/\(messageID)" let url = URL(string: urlAsString)! let request = TSRequest(url: url, method: "DELETE", parameters: [:]) request.allHTTPHeaderFields = [ "Content-Type" : "application/json", "Authorization" : "Bearer \(token)" ] @@ -186,27 +186,27 @@ public final class LokiGroupChatAPI : LokiDotNetAPI { } } - public static func getModerators(for group: UInt64, on server: String) -> Promise> { - let url = URL(string: "\(server)/loki/v1/channel/\(group)/get_moderators")! + public static func getModerators(for channel: UInt64, on server: String) -> Promise> { + let url = URL(string: "\(server)/loki/v1/channel/\(channel)/get_moderators")! let request = TSRequest(url: url) return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.map { rawResponse in guard let json = rawResponse as? JSON, let moderators = json["moderators"] as? [String] else { - print("[Loki] Couldn't parse moderators for group chat with ID: \(group) on server: \(server) from: \(rawResponse).") + print("[Loki] Couldn't parse moderators for public chat channel with ID: \(channel) on server: \(server) from: \(rawResponse).") throw Error.parsingFailed } let moderatorAsSet = Set(moderators); if self.moderators.keys.contains(server) { - self.moderators[server]![group] = moderatorAsSet + self.moderators[server]![channel] = moderatorAsSet } else { - self.moderators[server] = [ group : moderatorAsSet ] + self.moderators[server] = [ channel : moderatorAsSet ] } return moderatorAsSet } } @objc (isUserModerator:forGroup:onServer:) - public static func isUserModerator(_ hexEncodedPublicString: String, for group: UInt64, on server: String) -> Bool { - return moderators[server]?[group]?.contains(hexEncodedPublicString) ?? false + public static func isUserModerator(_ hexEncodedPublicString: String, for channel: UInt64, on server: String) -> Bool { + return moderators[server]?[channel]?.contains(hexEncodedPublicString) ?? false } public static func setDisplayName(to newDisplayName: String?, on server: String) -> Promise { @@ -216,27 +216,27 @@ public final class LokiGroupChatAPI : LokiDotNetAPI { let url = URL(string: "\(server)/users/me")! let request = TSRequest(url: url, method: "PATCH", parameters: parameters) request.allHTTPHeaderFields = [ "Content-Type" : "application/json", "Authorization" : "Bearer \(token)" ] - return TSNetworkManager.shared().makePromise(request: request).retryingIfNeeded(maxRetryCount: 3).map { _ in }.recover { error in + return TSNetworkManager.shared().makePromise(request: request).map { _ in }.recover { error in print("Couldn't update display name due to error: \(error).") throw error } - } + }.retryingIfNeeded(maxRetryCount: 3) } - public static func getChannelInfo(_ channel: UInt64, on server: String) -> Promise { + public static func getInfo(for channel: UInt64, on server: String) -> Promise { let url = URL(string: "\(server)/channels/\(channel)?include_annotations=1")! let request = TSRequest(url: url) return TSNetworkManager.shared().makePromise(request: request).map { $0.responseObject }.map { rawResponse in guard let json = rawResponse as? JSON, let data = json["data"] as? JSON, let annotations = data["annotations"] as? [JSON], - let infoAnnotation = annotations.first, - let info = infoAnnotation["value"] as? JSON, - let name = info["name"] as? String else { - print("[Loki] Couldn't parse info for group chat with ID: \(channel) on server: \(server) from: \(rawResponse).") + let annotation = annotations.first, + let info = annotation["value"] as? JSON, + let displayName = info["name"] as? String else { + print("[Loki] Couldn't parse info for public chat channel with ID: \(channel) on server: \(server) from: \(rawResponse).") throw Error.parsingFailed } - return name + return LokiPublicChatInfo(displayName: displayName) } } @@ -252,7 +252,7 @@ public final class LokiGroupChatAPI : LokiDotNetAPI { } @objc(sendMessage:toGroup:onServer:) - public static func objc_sendMessage(_ message: LokiGroupMessage, to group: UInt64, on server: String) -> AnyPromise { + public static func objc_sendMessage(_ message: LokiPublicChatMessage, to group: UInt64, on server: String) -> AnyPromise { return AnyPromise.from(sendMessage(message, to: group, on: server)) } diff --git a/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatInfo.swift b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatInfo.swift new file mode 100644 index 000000000..8195b24ac --- /dev/null +++ b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatInfo.swift @@ -0,0 +1,4 @@ + +public struct LokiPublicChatInfo { + public let displayName: String +} diff --git a/SignalServiceKit/src/Loki/API/Group Chat/LokiPublicChatManager.swift b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatManager.swift similarity index 82% rename from SignalServiceKit/src/Loki/API/Group Chat/LokiPublicChatManager.swift rename to SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatManager.swift index 772b0ad61..5825e7de9 100644 --- a/SignalServiceKit/src/Loki/API/Group Chat/LokiPublicChatManager.swift +++ b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatManager.swift @@ -11,7 +11,7 @@ public final class LokiPublicChatManager: NSObject { @objc public static let shared = LokiPublicChatManager() - private var chats: [String: LokiGroupChat] = [:] + private var chats: [String: LokiPublicChat] = [:] private var pollers: [String: GroupChatPoller] = [:] private var isPolling = false @@ -29,11 +29,11 @@ public final class LokiPublicChatManager: NSObject { } @objc public func startPollersIfNeeded() { - for (threadID, groupChat) in chats { + for (threadID, publicChat) in chats { if let poller = pollers[threadID] { poller.startIfNeeded() } else { - let poller = GroupChatPoller(for: groupChat) + let poller = GroupChatPoller(for: publicChat) poller.startIfNeeded() pollers[threadID] = poller } @@ -46,7 +46,7 @@ public final class LokiPublicChatManager: NSObject { isPolling = false } - public func addChat(server: String, channel: UInt64) -> Promise { + public func addChat(server: String, channel: UInt64) -> Promise { if let existingChat = getChat(server: server, channel: channel) { if let chat = self.addChat(server: server, channel: channel, name: existingChat.displayName) { return Promise.value(chat) @@ -55,18 +55,18 @@ public final class LokiPublicChatManager: NSObject { } } - return LokiGroupChatAPI.getAuthToken(for: server).then { token in - return LokiGroupChatAPI.getChannelInfo(channel, on: server) - }.map { channelInfo -> LokiGroupChat in - guard let chat = self.addChat(server: server, channel: channel, name: channelInfo) else { throw Error.chatCreationFailed } + return LokiPublicChatAPI.getAuthToken(for: server).then { token in + return LokiPublicChatAPI.getInfo(for: channel, on: server) + }.map { channelInfo -> LokiPublicChat in + guard let chat = self.addChat(server: server, channel: channel, name: channelInfo.displayName) else { throw Error.chatCreationFailed } return chat } } @discardableResult @objc(addChatWithServer:channel:name:) - public func addChat(server: String, channel: UInt64, name: String) -> LokiGroupChat? { - guard let chat = LokiGroupChat(channel: channel, server: server, displayName: name, isDeletable: true) else { return nil } + public func addChat(server: String, channel: UInt64, name: String) -> LokiPublicChat? { + guard let chat = LokiPublicChat(channel: channel, server: server, displayName: name, isDeletable: true) else { return nil } let model = TSGroupModel(title: chat.displayName, memberIds: [ourHexEncodedPublicKey!, chat.server], image: nil, groupId: chat.idAsData) // Store the group chat mapping @@ -85,7 +85,7 @@ public final class LokiPublicChatManager: NSObject { } // Save the group chat - LokiDatabaseUtilities.setGroupChat(chat, for: thread.uniqueId!, in: transaction) + LokiDatabaseUtilities.setPublicChat(chat, for: thread.uniqueId!, in: transaction) } // Update chats and pollers @@ -101,7 +101,7 @@ public final class LokiPublicChatManager: NSObject { private func refreshChatsAndPollers() { storage.dbReadConnection.read { transaction in - let newChats = LokiDatabaseUtilities.getAllGroupChats(in: transaction) + let newChats = LokiDatabaseUtilities.getAllPublicChats(in: transaction) // Remove any chats that don't exist in the database let removedChatThreadIds = self.chats.keys.filter { !newChats.keys.contains($0) } @@ -124,18 +124,18 @@ public final class LokiPublicChatManager: NSObject { // Reset the last message cache if let chat = self.chats[threadId] { - LokiGroupChatAPI.resetLastMessageCache(for: chat.channel, on: chat.server) + LokiPublicChatAPI.resetLastMessageCache(for: chat.channel, on: chat.server) } // Remove the chat from the db storage.dbReadWriteConnection.readWrite { transaction in - LokiDatabaseUtilities.removeGroupChat(for: threadId, in: transaction) + LokiDatabaseUtilities.removePublicChat(for: threadId, in: transaction) } refreshChatsAndPollers() } - private func getChat(server: String, channel: UInt64) -> LokiGroupChat? { + private func getChat(server: String, channel: UInt64) -> LokiPublicChat? { return chats.values.first { chat in return chat.server == server && chat.channel == channel } diff --git a/SignalServiceKit/src/Loki/API/Group Chat/LokiGroupMessage.swift b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatMessage.swift similarity index 91% rename from SignalServiceKit/src/Loki/API/Group Chat/LokiGroupMessage.swift rename to SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatMessage.swift index 0d90171c8..9baf2e072 100644 --- a/SignalServiceKit/src/Loki/API/Group Chat/LokiGroupMessage.swift +++ b/SignalServiceKit/src/Loki/API/Public Chat/LokiPublicChatMessage.swift @@ -1,7 +1,7 @@ import PromiseKit @objc(LKGroupMessage) -public final class LokiGroupMessage : NSObject { +public final class LokiPublicChatMessage : NSObject { public let serverID: UInt64? public let hexEncodedPublicKey: String public let displayName: String @@ -62,18 +62,18 @@ public final class LokiGroupMessage : NSObject { } // MARK: Crypto - internal func sign(with privateKey: Data) -> LokiGroupMessage? { + internal func sign(with privateKey: Data) -> LokiPublicChatMessage? { guard let data = getValidationData(for: signatureVersion) else { - print("[Loki] Failed to sign group chat message.") + print("[Loki] Failed to sign public chat message.") return nil } let userKeyPair = OWSIdentityManager.shared().identityKeyPair()! guard let signatureData = try? Ed25519.sign(data, with: userKeyPair) else { - print("[Loki] Failed to sign group chat message.") + print("[Loki] Failed to sign public chat message.") return nil } let signature = Signature(data: signatureData, version: signatureVersion) - return LokiGroupMessage(serverID: serverID, hexEncodedPublicKey: hexEncodedPublicKey, displayName: displayName, body: body, type: type, timestamp: timestamp, quote: quote, signature: signature) + return LokiPublicChatMessage(serverID: serverID, hexEncodedPublicKey: hexEncodedPublicKey, displayName: displayName, body: body, type: type, timestamp: timestamp, quote: quote, signature: signature) } internal func hasValidSignature() -> Bool { diff --git a/SignalServiceKit/src/Loki/API/Group Chat/LokiRSSFeed.swift b/SignalServiceKit/src/Loki/API/Public Chat/LokiRSSFeed.swift similarity index 100% rename from SignalServiceKit/src/Loki/API/Group Chat/LokiRSSFeed.swift rename to SignalServiceKit/src/Loki/API/Public Chat/LokiRSSFeed.swift diff --git a/SignalServiceKit/src/Loki/API/Group Chat/GroupChatPoller.swift b/SignalServiceKit/src/Loki/API/Public Chat/PublicChatPoller.swift similarity index 91% rename from SignalServiceKit/src/Loki/API/Group Chat/GroupChatPoller.swift rename to SignalServiceKit/src/Loki/API/Public Chat/PublicChatPoller.swift index 20435b8d4..5ac65b9f3 100644 --- a/SignalServiceKit/src/Loki/API/Group Chat/GroupChatPoller.swift +++ b/SignalServiceKit/src/Loki/API/Public Chat/PublicChatPoller.swift @@ -1,7 +1,7 @@ -@objc(LKGroupChatPoller) +@objc(LKPublicChatPoller) public final class GroupChatPoller : NSObject { - private let group: LokiGroupChat + private let group: LokiPublicChat private var pollForNewMessagesTimer: Timer? = nil private var pollForDeletedMessagesTimer: Timer? = nil private var pollForModeratorsTimer: Timer? = nil @@ -15,7 +15,7 @@ public final class GroupChatPoller : NSObject { // MARK: Lifecycle @objc(initForGroup:) - public init(for group: LokiGroupChat) { + public init(for group: LokiPublicChat) { self.group = group super.init() } @@ -45,7 +45,7 @@ public final class GroupChatPoller : NSObject { let group = self.group let userHexEncodedPublicKey = self.userHexEncodedPublicKey // Processing logic for incoming messages - func processIncomingMessage(_ message: LokiGroupMessage) { + func processIncomingMessage(_ message: LokiPublicChatMessage) { let senderHexEncodedPublicKey = message.hexEncodedPublicKey let endIndex = senderHexEncodedPublicKey.endIndex let cutoffIndex = senderHexEncodedPublicKey.index(endIndex, offsetBy: -8) @@ -80,7 +80,7 @@ public final class GroupChatPoller : NSObject { } } // Processing logic for outgoing messages - func processOutgoingMessage(_ message: LokiGroupMessage) { + func processOutgoingMessage(_ message: LokiPublicChatMessage) { guard let messageServerID = message.serverID else { return } let storage = OWSPrimaryStorage.shared() var isDuplicate = false @@ -102,7 +102,7 @@ public final class GroupChatPoller : NSObject { storage.dbReadWriteConnection.readWrite { transaction in message.update(withSentRecipient: group.server, wasSentByUD: false, transaction: transaction) message.saveGroupChatServerID(messageServerID, in: transaction) - guard let messageID = message.uniqueId else { return print("[Loki] Failed to save group message.") } + guard let messageID = message.uniqueId else { return print("[Loki] Failed to save public chat message.") } storage.setIDForMessageWithServerID(UInt(messageServerID), to: messageID, in: transaction) } if let linkPreviewURL = OWSLinkPreview.previewUrl(forMessageBodyText: message.body, selectedRange: nil) { @@ -110,7 +110,7 @@ public final class GroupChatPoller : NSObject { } } // Poll - let _ = LokiGroupChatAPI.getMessages(for: group.channel, on: group.server).done(on: .main) { messages in + let _ = LokiPublicChatAPI.getMessages(for: group.channel, on: group.server).done(on: .main) { messages in messages.forEach { message in if message.hexEncodedPublicKey != userHexEncodedPublicKey { processIncomingMessage(message) @@ -123,7 +123,7 @@ public final class GroupChatPoller : NSObject { private func pollForDeletedMessages() { let group = self.group - let _ = LokiGroupChatAPI.getDeletedMessageServerIDs(for: group.channel, on: group.server).done { deletedMessageServerIDs in + let _ = LokiPublicChatAPI.getDeletedMessageServerIDs(for: group.channel, on: group.server).done { deletedMessageServerIDs in let storage = OWSPrimaryStorage.shared() storage.dbReadWriteConnection.readWrite { transaction in let deletedMessageIDs = deletedMessageServerIDs.compactMap { storage.getIDForMessage(withServerID: UInt($0), in: transaction) } @@ -135,6 +135,6 @@ public final class GroupChatPoller : NSObject { } private func pollForModerators() { - let _ = LokiGroupChatAPI.getModerators(for: group.channel, on: group.server) + let _ = LokiPublicChatAPI.getModerators(for: group.channel, on: group.server) } } diff --git a/SignalServiceKit/src/Loki/Database/LokiDatabaseUtilities.swift b/SignalServiceKit/src/Loki/Database/LokiDatabaseUtilities.swift index 3e8796289..8e2c2abf5 100644 --- a/SignalServiceKit/src/Loki/Database/LokiDatabaseUtilities.swift +++ b/SignalServiceKit/src/Loki/Database/LokiDatabaseUtilities.swift @@ -27,31 +27,31 @@ public final class LokiDatabaseUtilities : NSObject { return OWSPrimaryStorage.shared().getMasterHexEncodedPublicKey(for: slaveHexEncodedPublicKey, in: transaction) } - // MARK: Group Chats - private static let groupChatCollection = "LokiGroupChatCollection" + // MARK: Public Chats + private static let publicChatCollection = "LokiPublicChatCollection" - @objc(getAllGroupChats:) - public static func getAllGroupChats(in transaction: YapDatabaseReadTransaction) -> [String:LokiGroupChat] { - var result = [String:LokiGroupChat]() - transaction.enumerateKeysAndObjects(inCollection: groupChatCollection) { threadID, object, _ in - guard let groupChat = object as? LokiGroupChat else { return } - result[threadID] = groupChat + @objc(getAllPublicChats:) + public static func getAllPublicChats(in transaction: YapDatabaseReadTransaction) -> [String:LokiPublicChat] { + var result = [String:LokiPublicChat]() + transaction.enumerateKeysAndObjects(inCollection: publicChatCollection) { threadID, object, _ in + guard let publicChat = object as? LokiPublicChat else { return } + result[threadID] = publicChat } return result } - @objc(getGroupChatForThreadID:transaction:) - public static func getGroupChat(for threadID: String, in transaction: YapDatabaseReadTransaction) -> LokiGroupChat? { - return transaction.object(forKey: threadID, inCollection: groupChatCollection) as? LokiGroupChat + @objc(getPublicChatForThreadID:transaction:) + public static func getPublicChat(for threadID: String, in transaction: YapDatabaseReadTransaction) -> LokiPublicChat? { + return transaction.object(forKey: threadID, inCollection: publicChatCollection) as? LokiPublicChat } - @objc(setGroupChat:threadID:transaction:) - public static func setGroupChat(_ groupChat: LokiGroupChat, for threadID: String, in transaction: YapDatabaseReadWriteTransaction) { - transaction.setObject(groupChat, forKey: threadID, inCollection: groupChatCollection) + @objc(setPublicChat:threadID:transaction:) + public static func setPublicChat(_ publicChat: LokiPublicChat, for threadID: String, in transaction: YapDatabaseReadWriteTransaction) { + transaction.setObject(publicChat, forKey: threadID, inCollection: publicChatCollection) } - @objc(removeGroupChatForThreadID:transaction:) - public static func removeGroupChat(for threadID: String, in transaction: YapDatabaseReadWriteTransaction) { - transaction.removeObject(forKey: threadID, inCollection: groupChatCollection) + @objc(removePublicChatForThreadID:transaction:) + public static func removePublicChat(for threadID: String, in transaction: YapDatabaseReadWriteTransaction) { + transaction.removeObject(forKey: threadID, inCollection: publicChatCollection) } } diff --git a/SignalServiceKit/src/Loki/Utilities/DisplayNameUtilities.swift b/SignalServiceKit/src/Loki/Utilities/DisplayNameUtilities.swift index e02cf92c2..8b76e226c 100644 --- a/SignalServiceKit/src/Loki/Utilities/DisplayNameUtilities.swift +++ b/SignalServiceKit/src/Loki/Utilities/DisplayNameUtilities.swift @@ -20,15 +20,15 @@ public final class DisplayNameUtilities : NSObject { } } - @objc public static func getGroupChatDisplayName(for hexEncodedPublicKey: String, in channel: UInt64, on server: String) -> String? { + @objc public static func getPublicChatDisplayName(for hexEncodedPublicKey: String, in channel: UInt64, on server: String) -> String? { var result: String? OWSPrimaryStorage.shared().dbReadConnection.read { transaction in - result = getGroupChatDisplayName(for: hexEncodedPublicKey, in: channel, on: server, using: transaction) + result = getPublicChatDisplayName(for: hexEncodedPublicKey, in: channel, on: server, using: transaction) } return result } - @objc public static func getGroupChatDisplayName(for hexEncodedPublicKey: String, in channel: UInt64, on server: String, using transaction: YapDatabaseReadTransaction) -> String? { + @objc public static func getPublicChatDisplayName(for hexEncodedPublicKey: String, in channel: UInt64, on server: String, using transaction: YapDatabaseReadTransaction) -> String? { if hexEncodedPublicKey == userHexEncodedPublicKey { return userDisplayName } else { diff --git a/SignalServiceKit/src/Messages/Interactions/TSMessage.h b/SignalServiceKit/src/Messages/Interactions/TSMessage.h index 682deb47d..70be6e19b 100644 --- a/SignalServiceKit/src/Messages/Interactions/TSMessage.h +++ b/SignalServiceKit/src/Messages/Interactions/TSMessage.h @@ -46,8 +46,8 @@ typedef NS_ENUM(NSInteger, LKMessageFriendRequestStatus) { @property (nonatomic, readonly) BOOL hasFriendRequestStatusMessage; @property (nonatomic) BOOL isP2P; // Group chat -@property (nonatomic) uint64_t groupChatServerID; -@property (nonatomic, readonly) BOOL isGroupChatMessage; +@property (nonatomic) uint64_t groupChatServerID; // Should ideally be publicChatServerID +@property (nonatomic, readonly) BOOL isGroupChatMessage; // Should ideally be isPublicChatMessage - (instancetype)initInteractionWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread NS_UNAVAILABLE; diff --git a/SignalServiceKit/src/Messages/OWSMessageSender.m b/SignalServiceKit/src/Messages/OWSMessageSender.m index 4b796818f..2d07a0f24 100644 --- a/SignalServiceKit/src/Messages/OWSMessageSender.m +++ b/SignalServiceKit/src/Messages/OWSMessageSender.m @@ -504,8 +504,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; [recipientIds addObject:self.tsAccountManager.localNumber]; } else if (thread.isGroupThread) { [self.primaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { - LKGroupChat *groupChat = [LKDatabaseUtilities getGroupChatForThreadID:thread.uniqueId transaction:transaction]; - [recipientIds addObject:groupChat.server]; + LKPublicChat *publicChat = [LKDatabaseUtilities getPublicChatForThreadID:thread.uniqueId transaction:transaction]; + if (publicChat != nil) { + [recipientIds addObject:publicChat.server]; + } else { + // TODO: Handle + } }]; } else if ([thread isKindOfClass:[TSContactThread class]]) { NSString *recipientContactId = ((TSContactThread *)thread).contactIdentifier; @@ -1188,11 +1192,11 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; [self messageSendDidFail:messageSend deviceMessages:deviceMessages statusCode:statusCode error:error responseData:responseData]; }; - __block LKGroupChat *groupChat; + __block LKPublicChat *publicChat; [OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) { - groupChat = [LKDatabaseUtilities getGroupChatForThreadID:message.uniqueThreadId transaction: transaction]; + publicChat = [LKDatabaseUtilities getPublicChatForThreadID:message.uniqueThreadId transaction: transaction]; }]; - if (groupChat != nil) { + if (publicChat != nil) { NSString *userHexEncodedPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey; NSString *displayName = SSKEnvironment.shared.profileManager.localProfileName; if (displayName == nil) { displayName = @"Anonymous"; } @@ -1205,9 +1209,9 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException"; quotedMessageServerID = [LKDatabaseUtilities getServerIDForQuoteWithID:quoteID quoteeHexEncodedPublicKey:quoteeHexEncodedPublicKey threadID:messageSend.thread.uniqueId transaction:transaction]; }]; } - LKGroupMessage *groupMessage = [[LKGroupMessage alloc] initWithHexEncodedPublicKey:userHexEncodedPublicKey displayName:displayName body:message.body type:LKGroupChatAPI.publicChatMessageType + LKGroupMessage *groupMessage = [[LKGroupMessage alloc] initWithHexEncodedPublicKey:userHexEncodedPublicKey displayName:displayName body:message.body type:LKPublicChatAPI.publicChatMessageType timestamp:message.timestamp quotedMessageTimestamp:quoteID quoteeHexEncodedPublicKey:quoteeHexEncodedPublicKey quotedMessageBody:quote.body quotedMessageServerID:quotedMessageServerID signatureData:nil signatureVersion:0]; - [[LKGroupChatAPI sendMessage:groupMessage toGroup:groupChat.channel onServer:groupChat.server] + [[LKPublicChatAPI sendMessage:groupMessage toGroup:publicChat.channel onServer:publicChat.server] .thenOn(OWSDispatch.sendingQueue, ^(LKGroupMessage *groupMessage) { [self.dbConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { [message saveGroupChatServerID:groupMessage.serverID in:transaction];