Skip to content

Commit

Permalink
Added PublicChatManager.
Browse files Browse the repository at this point in the history
Added migrations.
  • Loading branch information
Mikunj committed Oct 9, 2019
1 parent 683a5c1 commit d8d3328
Show file tree
Hide file tree
Showing 19 changed files with 237 additions and 83 deletions.
2 changes: 1 addition & 1 deletion Pods
Submodule Pods updated from a6c8ea to 68a1e4
4 changes: 0 additions & 4 deletions Signal.xcodeproj/project.pbxproj
Expand Up @@ -565,7 +565,6 @@
B821F2FA2272CEEE002C88C0 /* SeedVC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F92272CEEE002C88C0 /* SeedVC.swift */; };
B8258493230FA5E9001B41CB /* ScanQRCodeVC.m in Sources */ = {isa = PBXBuildFile; fileRef = B8258492230FA5E9001B41CB /* ScanQRCodeVC.m */; };
B82584A02315024B001B41CB /* RSSFeedPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B825849F2315024B001B41CB /* RSSFeedPoller.swift */; };
B845B4D4230CD09100D759F0 /* GroupChatPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B845B4D3230CD09000D759F0 /* GroupChatPoller.swift */; };
B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; };
B86BD08123399883000F5AE3 /* QRCodeModal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08023399883000F5AE3 /* QRCodeModal.swift */; };
B86BD08423399ACF000F5AE3 /* Modal.swift in Sources */ = {isa = PBXBuildFile; fileRef = B86BD08323399ACF000F5AE3 /* Modal.swift */; };
Expand Down Expand Up @@ -1374,7 +1373,6 @@
B8258491230FA5DA001B41CB /* ScanQRCodeVC.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ScanQRCodeVC.h; sourceTree = "<group>"; };
B8258492230FA5E9001B41CB /* ScanQRCodeVC.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = ScanQRCodeVC.m; sourceTree = "<group>"; };
B825849F2315024B001B41CB /* RSSFeedPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RSSFeedPoller.swift; sourceTree = "<group>"; };
B845B4D3230CD09000D759F0 /* GroupChatPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupChatPoller.swift; sourceTree = "<group>"; };
B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = "<group>"; };
B86BD08023399883000F5AE3 /* QRCodeModal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = QRCodeModal.swift; sourceTree = "<group>"; };
B86BD08323399ACF000F5AE3 /* Modal.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Modal.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -2699,7 +2697,6 @@
B86BD0892339A278000F5AE3 /* Group Chat */ = {
isa = PBXGroup;
children = (
B845B4D3230CD09000D759F0 /* GroupChatPoller.swift */,
B825849F2315024B001B41CB /* RSSFeedPoller.swift */,
);
path = "Group Chat";
Expand Down Expand Up @@ -3744,7 +3741,6 @@
34A4C62022175C5C0042EF2E /* OnboardingProfileViewController.swift in Sources */,
4505C2BF1E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */,
EF764C351DB67CC5000D9A87 /* UIViewController+Permissions.m in Sources */,
B845B4D4230CD09100D759F0 /* GroupChatPoller.swift in Sources */,
45CD81EF1DC030E7004C9430 /* SyncPushTokensJob.swift in Sources */,
34D2CCE0206939B400CB1A14 /* DebugUIMessagesAssetLoader.m in Sources */,
4CEB78C92178EBAB00F315D2 /* OWSSessionResetJobRecord.m in Sources */,
Expand Down
56 changes: 13 additions & 43 deletions Signal/src/AppDelegate.m
Expand Up @@ -69,7 +69,6 @@ @interface AppDelegate () <UNUserNotificationCenterDelegate>
// Loki
@property (nonatomic) LKP2PServer *lokiP2PServer;
@property (nonatomic) LKLongPoller *lokiLongPoller;
@property (nonatomic) LKGroupChatPoller *lokiPublicChatPoller;
@property (nonatomic) LKRSSFeedPoller *lokiNewsFeedPoller;
@property (nonatomic) LKRSSFeedPoller *lokiMessengerUpdatesFeedPoller;

Expand Down Expand Up @@ -1525,11 +1524,6 @@ - (void)stopLongPollerIfNeeded
[self.lokiLongPoller stopIfNeeded];
}

- (LKGroupChat *)lokiPublicChat
{
return [[LKGroupChat alloc] initWithChannel:LKGroupChatAPI.publicChatServerID server:LKGroupChatAPI.publicChatServer displayName:NSLocalizedString(@"Loki Public Chat", @"") isDeletable:true];
}

- (LKRSSFeed *)lokiNewsFeed
{
return [[LKRSSFeed alloc] initWithId:@"loki.network.feed" server:@"https://loki.network/feed/" displayName:NSLocalizedString(@"Loki News", @"") isDeletable:true];
Expand All @@ -1542,25 +1536,18 @@ - (LKRSSFeed *)lokiMessengerUpdatesFeed

- (void)createGroupChatsIfNeeded
{
LKGroupChat *publicChat = self.lokiPublicChat;
NSString *userHexEncodedPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey;
NSString *userDefaultsKey = [@"isGroupChatSetUp." stringByAppendingString:publicChat.id];
BOOL isChatSetUp = [NSUserDefaults.standardUserDefaults boolForKey:userDefaultsKey];
if (!isChatSetUp || !publicChat.isDeletable) {
TSGroupModel *group = [[TSGroupModel alloc] initWithTitle:publicChat.displayName memberIds:@[ userHexEncodedPublicKey, publicChat.server ] image:nil groupId:[publicChat.id 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];
[NSUserDefaults.standardUserDefaults setBool:YES forKey:userDefaultsKey];
// Setup our default public chats
for (LKGroupChat *chat in LKGroupChat.defaultChats) {
NSString *userDefaultsKey = [@"isGroupChatSetUp." stringByAppendingString:chat.id];
BOOL isChatSetUp = [NSUserDefaults.standardUserDefaults boolForKey:userDefaultsKey];
if (!isChatSetUp || !chat.isDeletable) {
[LKPublicChatManager.shared addChatWithServer:chat.server channel:chat.channel name:chat.displayName];
[OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
TSGroupThread *thread = [TSGroupThread threadWithGroupId:chat.idAsData transaction:transaction];
if (thread != nil) { [OWSProfileManager.sharedManager addThreadToProfileWhitelist:thread]; }
}];
[NSUserDefaults.standardUserDefaults setBool:YES forKey:userDefaultsKey];
}
}
}

Expand Down Expand Up @@ -1590,18 +1577,6 @@ - (void)createRSSFeedsIfNeeded
}
}

- (void)createGroupChatPollersIfNeeded
{
// Only create the group chat pollers if their threads aren't deleted
__block TSGroupThread *thread;
[OWSPrimaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
thread = [TSGroupThread threadWithGroupId:[self.lokiPublicChat.id dataUsingEncoding:NSUTF8StringEncoding] transaction:transaction];
}];
if (thread != nil && self.lokiPublicChatPoller == nil) {
self.lokiPublicChatPoller = [[LKGroupChatPoller alloc] initForGroup:self.lokiPublicChat];
}
}

- (void)createRSSFeedPollersIfNeeded
{
// Only create the RSS feed pollers if their threads aren't deleted
Expand All @@ -1620,8 +1595,7 @@ - (void)createRSSFeedPollersIfNeeded

- (void)startGroupChatPollersIfNeeded
{
[self createGroupChatPollersIfNeeded];
if (self.lokiPublicChatPoller != nil) { [self.lokiPublicChatPoller startIfNeeded]; }
[LKPublicChatManager.shared startPollersIfNeeded];
}

- (void)startRSSFeedPollersIfNeeded
Expand All @@ -1635,10 +1609,6 @@ - (void)handleThreadDeleted:(NSNotification *)notification {
NSDictionary *userInfo = notification.userInfo;
NSString *threadID = (NSString *)userInfo[@"threadId"];
if (threadID == nil) { return; }
if ([threadID isEqualToString:[TSGroupThread threadIdFromGroupId:[self.lokiPublicChat.id dataUsingEncoding:NSUTF8StringEncoding]]] && self.lokiPublicChatPoller != nil) {
[self.lokiPublicChatPoller stop];
self.lokiPublicChatPoller = nil;
}
if ([threadID isEqualToString:[TSGroupThread threadIdFromGroupId:[self.lokiNewsFeed.id dataUsingEncoding:NSUTF8StringEncoding]]] && self.lokiNewsFeedPoller != nil) {
[self.lokiNewsFeedPoller stop];
self.lokiNewsFeedPoller = nil;
Expand Down
Expand Up @@ -13,6 +13,7 @@
#import <SignalMessaging/UIView+OWS.h>
#import <SignalServiceKit/TSAttachmentStream.h>
#import <SignalServiceKit/TSMessage.h>
#import <SignalServiceKit/SignalServiceKit-Swift.h>

NS_ASSUME_NONNULL_BEGIN

Expand Down Expand Up @@ -553,10 +554,12 @@ - (UILabel *)configureQuotedAuthorLabel

if (quotedAuthor == self.quotedMessage.authorId) {
[OWSPrimaryStorage.sharedManager.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
// TODO: Fix this to use dynamic LKGroup variables!
NSString *collection = [NSString stringWithFormat:@"%@.%@", LKGroupChatAPI.publicChatServer, @(LKGroupChatAPI.publicChatServerID)];
NSString *displayName = [transaction stringForKey:self.quotedMessage.authorId inCollection:collection];
if (displayName != nil) { quotedAuthor = displayName; }
LKGroupChat *chat = [LKDatabaseUtilities getGroupChatForThreadID:self.quotedMessage.threadId transaction:transaction];
if (chat != nil) {
NSString *collection = [NSString stringWithFormat:@"%@.%@", chat.server, @(chat.channel)];
NSString *displayName = [transaction stringForKey:self.quotedMessage.authorId inCollection:collection];
if (displayName != nil) { quotedAuthor = displayName; }
}
}];
}

Expand Down
Expand Up @@ -2598,6 +2598,7 @@ - (void)populateReplyForViewItem:(id<ConversationViewItem>)conversationItem
__block OWSQuotedReplyModel *quotedReply;
[self.uiDatabaseConnection readWithBlock:^(YapDatabaseReadTransaction *transaction) {
quotedReply = [OWSQuotedReplyModel quotedReplyForSendingWithConversationViewItem:conversationItem
threadId:conversationItem.interaction.uniqueThreadId
transaction:transaction];
}];

Expand Down
Expand Up @@ -620,7 +620,7 @@ - (void)ensureViewState:(YapDatabaseReadTransaction *)transaction
// since that logic may exit early.
if (message.quotedMessage) {
self.quotedReply =
[OWSQuotedReplyModel quotedReplyWithQuotedMessage:message.quotedMessage transaction:transaction];
[OWSQuotedReplyModel quotedReplyWithQuotedMessage:message.quotedMessage threadId:message.uniqueThreadId transaction:transaction];

if (self.quotedReply.body.length > 0) {
self.displayableQuotedText =
Expand Down
5 changes: 2 additions & 3 deletions Signal/src/ViewControllers/DebugUI/DebugUIMessages.m
Expand Up @@ -2016,7 +2016,7 @@ + (DebugUIMessagesAction *)fakeRandomTextAction:(TSThread *)thread
transaction:transaction
conversationStyle:conversationStyle];
quotedMessage = [
[OWSQuotedReplyModel quotedReplyForSendingWithConversationViewItem:viewItem transaction:transaction]
[OWSQuotedReplyModel quotedReplyForSendingWithConversationViewItem:viewItem threadId:viewItem.interaction.uniqueThreadId transaction:transaction]
buildQuotedMessageForSending];
} else {
TSOutgoingMessage *_Nullable messageToQuote = [self createFakeOutgoingMessage:thread
Expand All @@ -2037,8 +2037,7 @@ + (DebugUIMessagesAction *)fakeRandomTextAction:(TSThread *)thread
isRSSFeed:NO
transaction:transaction
conversationStyle:conversationStyle];
quotedMessage = [
[OWSQuotedReplyModel quotedReplyForSendingWithConversationViewItem:viewItem transaction:transaction]
quotedMessage = [[OWSQuotedReplyModel quotedReplyForSendingWithConversationViewItem:viewItem threadId:viewItem.interaction.uniqueThreadId transaction:transaction]
buildQuotedMessageForSending];
}
OWSAssertDebug(quotedMessage);
Expand Down
6 changes: 6 additions & 0 deletions SignalMessaging/ViewModels/OWSQuotedReplyModel.h
Expand Up @@ -40,14 +40,20 @@ NS_ASSUME_NONNULL_BEGIN

// Used for persisted quoted replies, both incoming and outgoing.
+ (instancetype)quotedReplyWithQuotedMessage:(TSQuotedMessage *)quotedMessage
threadId:(NSString *)threadId
transaction:(YapDatabaseReadTransaction *)transaction;

// Builds a not-yet-sent QuotedReplyModel
+ (nullable instancetype)quotedReplyForSendingWithConversationViewItem:(id<ConversationViewItem>)conversationItem
threadId:(NSString *)threadId
transaction:(YapDatabaseReadTransaction *)transaction;

- (TSQuotedMessage *)buildQuotedMessageForSending;

// Loki

@property (nonatomic, readonly) NSString *threadId;


@end

Expand Down
16 changes: 12 additions & 4 deletions SignalMessaging/ViewModels/OWSQuotedReplyModel.m
Expand Up @@ -31,7 +31,8 @@ - (instancetype)initWithTimestamp:(uint64_t)timestamp
sourceFilename:(nullable NSString *)sourceFilename
attachmentStream:(nullable TSAttachmentStream *)attachmentStream
thumbnailAttachmentPointer:(nullable TSAttachmentPointer *)thumbnailAttachmentPointer
thumbnailDownloadFailed:(BOOL)thumbnailDownloadFailed NS_DESIGNATED_INITIALIZER;
thumbnailDownloadFailed:(BOOL)thumbnailDownloadFailed
threadId:(NSString *)threadId NS_DESIGNATED_INITIALIZER;

@end

Expand All @@ -50,6 +51,7 @@ - (instancetype)initWithTimestamp:(uint64_t)timestamp
attachmentStream:(nullable TSAttachmentStream *)attachmentStream
thumbnailAttachmentPointer:(nullable TSAttachmentPointer *)thumbnailAttachmentPointer
thumbnailDownloadFailed:(BOOL)thumbnailDownloadFailed
threadId:(NSString *)threadId
{
self = [super init];
if (!self) {
Expand All @@ -66,13 +68,15 @@ - (instancetype)initWithTimestamp:(uint64_t)timestamp
_attachmentStream = attachmentStream;
_thumbnailAttachmentPointer = thumbnailAttachmentPointer;
_thumbnailDownloadFailed = thumbnailDownloadFailed;
_threadId = threadId;

return self;
}

#pragma mark - Factory Methods

+ (instancetype)quotedReplyWithQuotedMessage:(TSQuotedMessage *)quotedMessage
threadId:(NSString *)threadId
transaction:(YapDatabaseReadTransaction *)transaction
{
OWSAssertDebug(quotedMessage.quotedAttachments.count <= 1);
Expand Down Expand Up @@ -112,10 +116,12 @@ + (instancetype)quotedReplyWithQuotedMessage:(TSQuotedMessage *)quotedMessage
sourceFilename:attachmentInfo.sourceFilename
attachmentStream:nil
thumbnailAttachmentPointer:attachmentPointer
thumbnailDownloadFailed:thumbnailDownloadFailed];
thumbnailDownloadFailed:thumbnailDownloadFailed
threadId:threadId];
}

+ (nullable instancetype)quotedReplyForSendingWithConversationViewItem:(id<ConversationViewItem>)conversationItem
threadId:(NSString *)threadId
transaction:(YapDatabaseReadTransaction *)transaction;
{
OWSAssertDebug(conversationItem);
Expand Down Expand Up @@ -160,7 +166,8 @@ + (nullable instancetype)quotedReplyForSendingWithConversationViewItem:(id<Conve
sourceFilename:nil
attachmentStream:nil
thumbnailAttachmentPointer:nil
thumbnailDownloadFailed:NO];
thumbnailDownloadFailed:NO
threadId:@""];
}

NSString *_Nullable quotedText = message.body;
Expand Down Expand Up @@ -237,7 +244,8 @@ + (nullable instancetype)quotedReplyForSendingWithConversationViewItem:(id<Conve
sourceFilename:quotedAttachment.sourceFilename
attachmentStream:quotedAttachment
thumbnailAttachmentPointer:nil
thumbnailDownloadFailed:NO];
thumbnailDownloadFailed:NO
threadId:threadId];
}

#pragma mark - Instance Methods
Expand Down
20 changes: 20 additions & 0 deletions SignalMessaging/environment/VersionMigrations.m
Expand Up @@ -93,6 +93,11 @@ + (void)performUpdateCheckWithCompletion:(VersionMigrationCompletion)completion
if ([self isVersion:previousVersion atLeast:@"2.0.0" andLessThan:@"2.3.0"] && [self.tsAccountManager isRegistered]) {
[self clearBloomFilterCache];
}

// Loki
if ([self isVersion:previousVersion lessThan:@"1.2.1"] && [self.tsAccountManager isRegistered]) {
[self updatePublicChatMapping];
}

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[[[OWSDatabaseMigrationRunner alloc] init] runAllOutstandingWithCompletion:completion];
Expand Down Expand Up @@ -162,6 +167,21 @@ + (void)clearBloomFilterCache
}
}

# pragma mark Loki - Upgrading to public chat manager

// Versions less than or equal to 1.2.0 didn't store group chat mappings
+ (void)updatePublicChatMapping
{
[OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction * _Nonnull transaction) {
for (LKGroupChat *chat in LKGroupChat.defaultChats) {
TSGroupThread *thread = [TSGroupThread threadWithGroupId:chat.idAsData transaction:transaction];
if (thread != nil) {
[LKDatabaseUtilities setGroupChat:chat threadID:thread.uniqueId transaction:transaction];
}
}
}];
}

@end

NS_ASSUME_NONNULL_END
18 changes: 10 additions & 8 deletions SignalMessaging/profiles/OWSProfileManager.m
Expand Up @@ -535,14 +535,16 @@ - (void)updateServiceWithProfileName:(nullable NSString *)localProfileName
OWSAssertDebug(successBlock);
OWSAssertDebug(failureBlock);

// TODO: Fix this to set display name on all servers
[[LKGroupChatAPI setDisplayName:localProfileName on:LKGroupChatAPI.publicChatServer]
.thenOn(dispatch_get_main_queue(), ^() {
successBlock();
})
.catchOn(dispatch_get_main_queue(), ^(NSError *error) {
failureBlock(error);
}) retainUntilComplete];
__block NSDictionary *chats;
[SSKEnvironment.shared.primaryStorage.dbReadConnection readWithBlock:^(YapDatabaseReadTransaction * _Nonnull transaction) {
chats = [LKDatabaseUtilities getAllGroupChats:transaction];
}];

for (LKGroupChat *chat in chats.allValues) {
[[LKGroupChatAPI setDisplayName:localProfileName on:chat.server] retainUntilComplete];
}

successBlock();
}

- (void)fetchLocalUsersProfile
Expand Down
@@ -0,0 +1,3 @@
public struct LokiPublicChannel {
public let name: String
}
14 changes: 12 additions & 2 deletions SignalServiceKit/src/Loki/API/Group Chat/LokiGroupChat.swift
@@ -1,10 +1,20 @@

@objc(LKGroupChat)
public final class LokiGroupChat : NSObject, NSCoding {
@objc public var id: String {
return "\(server).\(channel)"

@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)]

#if DEBUG
chats.append(LokiGroupChat(channel: UInt64(1), server: "https://chat-dev.lokinet.org", displayName: "Loki Dev Chat", isDeletable: true))
#endif

return chats
}

@objc public var id: String { return "\(server).\(channel)" }
@objc public var idAsData: Data? { return id.data(using: .utf8) }

@objc public let channel: UInt64
@objc public let server: String
@objc public let displayName: String
Expand Down

0 comments on commit d8d3328

Please sign in to comment.