From 3930891a3df55e381be7c7b1b39f27ba9e4742a2 Mon Sep 17 00:00:00 2001 From: Mikunj Date: Tue, 27 Aug 2019 10:44:00 +1000 Subject: [PATCH] Added dictionary for adding more servers. Updated group chat poller to take an array of groups. --- Signal/src/AppDelegate.m | 112 ++++++++++++++++++---- Signal/src/Loki/LokiGroupChatPoller.swift | 76 +++++++++------ 2 files changed, 138 insertions(+), 50 deletions(-) diff --git a/Signal/src/AppDelegate.m b/Signal/src/AppDelegate.m index fe9d21603..3267d03fd 100644 --- a/Signal/src/AppDelegate.m +++ b/Signal/src/AppDelegate.m @@ -56,6 +56,13 @@ static NSString *const kInitialViewControllerIdentifier = @"UserInitialViewContr static NSString *const kURLSchemeSGNLKey = @"sgnl"; static NSString *const kURLHostVerifyPrefix = @"verify"; +static NSString *const kChatID = @"PublicChatID"; +static NSString *const kChatType = @"PublicChatType"; +static NSString *const kChatServerURL = @"PublicChatServerURL"; +static NSString *const kChatName = @"PublicChatName"; +static NSString *const kChatClosable = @"PublicChatClosable"; +static NSString *const kChatChannelID = @"PublicChatChannelID"; + static NSTimeInterval launchStartedAt; @interface AppDelegate () @@ -1485,28 +1492,93 @@ static NSTimeInterval launchStartedAt; #pragma mark - Loki +- (NSArray *)publicChats +{ + return @[ + @{ + kChatID: @"chat.lokinet.org.1", + kChatType: @"publicChat", + kChatServerURL: LKGroupChatAPI.publicChatServer, + kChatName: NSLocalizedString(@"Loki Public Chat", @""), + kChatClosable: @true, + kChatChannelID: @(LKGroupChatAPI.publicChatID), + }, + @{ + kChatID: @"rss://loki.network/feed/", + kChatType: @"rss", + kChatServerURL: @"https://loki.network/feed/", + kChatName: NSLocalizedString(@"Loki.network News", @""), + kChatClosable: @true, + kChatChannelID: @1, + }, + @{ + kChatID: @"rss://loki.network/category/messenger-updates/feed/", + kChatType: @"rss", + kChatServerURL: @"https://loki.network/category/messenger-updates/feed/", + kChatName: NSLocalizedString(@"Messenger updates", @""), + kChatClosable: @false, + kChatChannelID: @1, + } + ]; +} + +- (void)setupPublicChatGroupsIfNeeded +{ + NSArray *chats = [self publicChats]; + NSString *ourPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey; + for (NSDictionary *chat in chats) { + NSString *chatID = [chat objectForKey:kChatID]; + BOOL closable = [[chat objectForKey:kChatClosable] boolValue]; + + NSString *setupKey = [@"setup-" stringByAppendingString:chatID]; + if (closable) { + BOOL isChatSetup = [NSUserDefaults.standardUserDefaults boolForKey:setupKey]; + if (isChatSetup) { continue; } + } + + NSString *title = [chat objectForKey:kChatName]; + NSString *serverURL = [chat objectForKey:kChatServerURL]; + + // Create the group threads + TSGroupModel *group = [[TSGroupModel alloc] initWithTitle:title memberIds:@[ ourPublicKey, serverURL ] image:nil groupId:[chatID dataUsingEncoding:NSUTF8StringEncoding]]; + __block TSGroupThread *thread; + [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { + thread = [TSGroupThread getOrCreateThreadWithGroupModel:group transaction:transaction]; + NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"]; + NSCalendar *calendar = NSCalendar.currentCalendar; + [calendar setTimeZone:timeZone]; + NSDateComponents *dateComponents = [NSDateComponents new]; + [dateComponents setYear:999]; + NSDate *date = [calendar dateByAddingComponents:dateComponents toDate:[NSDate new] options:0]; + [thread updateWithMutedUntilDate:date transaction:transaction]; + }]; + + [OWSProfileManager.sharedManager addThreadToProfileWhitelist:thread]; + if (closable) { + [NSUserDefaults.standardUserDefaults setBool:YES forKey:setupKey]; + } + } +} + - (void)setUpPublicChatIfNeeded { - if (self.lokiPublicChatPoller != nil) { return; } - self.lokiPublicChatPoller = [[LKGroupChatPoller alloc] initForGroup:(NSUInteger)LKGroupChatAPI.publicChatID onServer:LKGroupChatAPI.publicChatServer]; - BOOL isPublicChatSetUp = [NSUserDefaults.standardUserDefaults boolForKey:@"isPublicChatSetUp"]; - if (isPublicChatSetUp) { return; } - NSString *title = NSLocalizedString(@"Loki Public Chat", @""); - NSData *groupID = [[[LKGroupChatAPI.publicChatServer stringByAppendingString:@"."] stringByAppendingString:@(LKGroupChatAPI.publicChatID).stringValue] dataUsingEncoding:NSUTF8StringEncoding]; - TSGroupModel *group = [[TSGroupModel alloc] initWithTitle:title memberIds:@[ OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey, LKGroupChatAPI.publicChatServer ] image:nil groupId:groupID]; - __block TSGroupThread *thread; - [OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) { - thread = [TSGroupThread getOrCreateThreadWithGroupModel:group transaction:transaction]; - NSTimeZone *timeZone = [NSTimeZone timeZoneWithName:@"UTC"]; - NSCalendar *calendar = NSCalendar.currentCalendar; - [calendar setTimeZone:timeZone]; - NSDateComponents *dateComponents = [NSDateComponents new]; - [dateComponents setYear:999]; - NSDate *date = [calendar dateByAddingComponents:dateComponents toDate:[NSDate new] options:0]; - [thread updateWithMutedUntilDate:date transaction:transaction]; - }]; - [OWSProfileManager.sharedManager addThreadToProfileWhitelist:thread]; - [NSUserDefaults.standardUserDefaults setBool:YES forKey:@"isPublicChatSetUp"]; + static dispatch_once_t groupChatSetup; + dispatch_once(&groupChatSetup, ^{ + [self setupPublicChatGroupsIfNeeded]; + }); + [self setupPublicChatPollersIfNeeded]; +} + +- (void)setupPublicChatPollersIfNeeded +{ + if (self.lokiPublicChatPoller == nil) { + NSArray *publicChats = [[self publicChats] filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(id object, NSDictionary* bindings) { + NSDictionary *group = (NSDictionary *)object; + NSString *chatType = [group objectForKey:kChatType]; + return [chatType isEqualToString:@"publicChat"]; + }]]; + self.lokiPublicChatPoller = [[LKGroupChatPoller alloc] initWithGroups:publicChats]; + } } - (void)startPublicChatPollingIfNeeded diff --git a/Signal/src/Loki/LokiGroupChatPoller.swift b/Signal/src/Loki/LokiGroupChatPoller.swift index 4acaf58e8..b8918da0b 100644 --- a/Signal/src/Loki/LokiGroupChatPoller.swift +++ b/Signal/src/Loki/LokiGroupChatPoller.swift @@ -1,8 +1,12 @@ +private let kChatID = "PublicChatID" +private let kChatChannelID = "PublicChatChannelID" +private let kChatName = "PublicChatName" +private let kServerURL = "PublicChatServerURL" + @objc(LKGroupChatPoller) public final class LokiGroupChatPoller : NSObject { - private let group: UInt - private let server: String + private let groups: [[String: Any]] private var pollForNewMessagesTimer: Timer? = nil private var pollForDeletedMessagesTimer: Timer? = nil private var hasStarted = false @@ -10,10 +14,8 @@ public final class LokiGroupChatPoller : NSObject { private let pollForNewMessagesInterval: TimeInterval = 4 private let pollForDeletedMessagesInterval: TimeInterval = 120 - @objc(initForGroup:onServer:) - public init(for group: UInt, on server: String) { - self.group = group - self.server = server + @objc public init(groups: [[String: Any]]) { + self.groups = groups super.init() } @@ -31,30 +33,44 @@ public final class LokiGroupChatPoller : NSObject { } private func pollForNewMessages() { - let group = self.group - let server = self.server - let _ = LokiGroupChatAPI.getMessages(for: group, on: server).map { messages in - messages.reversed().map { message in - let id = "\(server).\(group)".data(using: String.Encoding.utf8)! - let x1 = SSKProtoGroupContext.builder(id: id, type: .deliver) - x1.setName(NSLocalizedString("Loki Public Chat", comment: "")) - let x2 = SSKProtoDataMessage.builder() - x2.setTimestamp(message.timestamp) - x2.setGroup(try! x1.build()) - x2.setBody(message.body) - let x3 = SSKProtoContent.builder() - x3.setDataMessage(try! x2.build()) - let x4 = SSKProtoEnvelope.builder(type: .ciphertext, timestamp: message.timestamp) - let senderHexEncodedPublicKey = message.hexEncodedPublicKey - let endIndex = senderHexEncodedPublicKey.endIndex - let cutoffIndex = senderHexEncodedPublicKey.index(endIndex, offsetBy: -8) - let senderDisplayName = "\(message.displayName) (...\(senderHexEncodedPublicKey[cutoffIndex.. Void { + guard let groupID = group[kChatID] as? String, let groupName = group[kChatName] as? String else { + Logger.info("[Loki] Failed to handle messages for group: \(group))") + return + } + + messages.reversed().forEach { message in + let id = groupID.data(using: String.Encoding.utf8)! + let x1 = SSKProtoGroupContext.builder(id: id, type: .deliver) + x1.setName(groupName) + let x2 = SSKProtoDataMessage.builder() + x2.setTimestamp(message.timestamp) + x2.setGroup(try! x1.build()) + x2.setBody(message.body) + let x3 = SSKProtoContent.builder() + x3.setDataMessage(try! x2.build()) + let x4 = SSKProtoEnvelope.builder(type: .ciphertext, timestamp: message.timestamp) + let senderHexEncodedPublicKey = message.hexEncodedPublicKey + let endIndex = senderHexEncodedPublicKey.endIndex + let cutoffIndex = senderHexEncodedPublicKey.index(endIndex, offsetBy: -8) + let senderDisplayName = "\(message.displayName) (...\(senderHexEncodedPublicKey[cutoffIndex..