mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Implement group message sending & receiving
This commit is contained in:
parent
b48a3626fb
commit
48706d233f
|
@ -560,6 +560,7 @@
|
||||||
B8162F0522892C5F00D46544 /* FriendRequestViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */; };
|
B8162F0522892C5F00D46544 /* FriendRequestViewDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */; };
|
||||||
B821F2F82272CED3002C88C0 /* AccountDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F72272CED3002C88C0 /* AccountDetailsViewController.swift */; };
|
B821F2F82272CED3002C88C0 /* AccountDetailsViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F72272CED3002C88C0 /* AccountDetailsViewController.swift */; };
|
||||||
B821F2FA2272CEEE002C88C0 /* SeedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F92272CEEE002C88C0 /* SeedViewController.swift */; };
|
B821F2FA2272CEEE002C88C0 /* SeedViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B821F2F92272CEEE002C88C0 /* SeedViewController.swift */; };
|
||||||
|
B845B4D4230CD09100D759F0 /* LokiGroupChatPoller.swift in Sources */ = {isa = PBXBuildFile; fileRef = B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */; };
|
||||||
B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; };
|
B846365B22B7418B00AF1514 /* Identicon+ObjC.swift in Sources */ = {isa = PBXBuildFile; fileRef = B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */; };
|
||||||
B89841E322B7579F00B1BDC6 /* NewConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */; };
|
B89841E322B7579F00B1BDC6 /* NewConversationViewController.swift in Sources */ = {isa = PBXBuildFile; fileRef = B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */; };
|
||||||
B90418E6183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; };
|
B90418E6183E9DD40038554A /* DateUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = B90418E5183E9DD40038554A /* DateUtil.m */; };
|
||||||
|
@ -1349,6 +1350,7 @@
|
||||||
B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendRequestViewDelegate.swift; sourceTree = "<group>"; };
|
B8162F0422892C5F00D46544 /* FriendRequestViewDelegate.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FriendRequestViewDelegate.swift; sourceTree = "<group>"; };
|
||||||
B821F2F72272CED3002C88C0 /* AccountDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDetailsViewController.swift; sourceTree = "<group>"; };
|
B821F2F72272CED3002C88C0 /* AccountDetailsViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AccountDetailsViewController.swift; sourceTree = "<group>"; };
|
||||||
B821F2F92272CEEE002C88C0 /* SeedViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedViewController.swift; sourceTree = "<group>"; };
|
B821F2F92272CEEE002C88C0 /* SeedViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SeedViewController.swift; sourceTree = "<group>"; };
|
||||||
|
B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = LokiGroupChatPoller.swift; sourceTree = "<group>"; };
|
||||||
B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = "<group>"; };
|
B846365A22B7418B00AF1514 /* Identicon+ObjC.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "Identicon+ObjC.swift"; sourceTree = "<group>"; };
|
||||||
B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewConversationViewController.swift; sourceTree = "<group>"; };
|
B89841E222B7579F00B1BDC6 /* NewConversationViewController.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = NewConversationViewController.swift; sourceTree = "<group>"; };
|
||||||
B90418E4183E9DD40038554A /* DateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateUtil.h; sourceTree = "<group>"; };
|
B90418E4183E9DD40038554A /* DateUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DateUtil.h; sourceTree = "<group>"; };
|
||||||
|
@ -2612,6 +2614,7 @@
|
||||||
B821F2F72272CED3002C88C0 /* AccountDetailsViewController.swift */,
|
B821F2F72272CED3002C88C0 /* AccountDetailsViewController.swift */,
|
||||||
B821F2F92272CEEE002C88C0 /* SeedViewController.swift */,
|
B821F2F92272CEEE002C88C0 /* SeedViewController.swift */,
|
||||||
24A830A12293CD0100F4CAC0 /* LokiP2PServer.swift */,
|
24A830A12293CD0100F4CAC0 /* LokiP2PServer.swift */,
|
||||||
|
B845B4D3230CD09000D759F0 /* LokiGroupChatPoller.swift */,
|
||||||
);
|
);
|
||||||
path = Loki;
|
path = Loki;
|
||||||
sourceTree = "<group>";
|
sourceTree = "<group>";
|
||||||
|
@ -3627,6 +3630,7 @@
|
||||||
34A4C62022175C5C0042EF2E /* OnboardingProfileViewController.swift in Sources */,
|
34A4C62022175C5C0042EF2E /* OnboardingProfileViewController.swift in Sources */,
|
||||||
4505C2BF1E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */,
|
4505C2BF1E648EA300CEBF41 /* ExperienceUpgrade.swift in Sources */,
|
||||||
EF764C351DB67CC5000D9A87 /* UIViewController+Permissions.m in Sources */,
|
EF764C351DB67CC5000D9A87 /* UIViewController+Permissions.m in Sources */,
|
||||||
|
B845B4D4230CD09100D759F0 /* LokiGroupChatPoller.swift in Sources */,
|
||||||
45CD81EF1DC030E7004C9430 /* SyncPushTokensJob.swift in Sources */,
|
45CD81EF1DC030E7004C9430 /* SyncPushTokensJob.swift in Sources */,
|
||||||
34D2CCE0206939B400CB1A14 /* DebugUIMessagesAssetLoader.m in Sources */,
|
34D2CCE0206939B400CB1A14 /* DebugUIMessagesAssetLoader.m in Sources */,
|
||||||
4CEB78C92178EBAB00F315D2 /* OWSSessionResetJobRecord.m in Sources */,
|
4CEB78C92178EBAB00F315D2 /* OWSSessionResetJobRecord.m in Sources */,
|
||||||
|
|
|
@ -8,4 +8,6 @@ extern NSString *const AppDelegateStoryboardMain;
|
||||||
|
|
||||||
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
@interface AppDelegate : UIResponder <UIApplicationDelegate>
|
||||||
|
|
||||||
|
- (void)startPublicChatPollingIfNeeded;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
|
@ -63,7 +63,8 @@ static NSTimeInterval launchStartedAt;
|
||||||
@property (nonatomic) BOOL hasInitialRootViewController;
|
@property (nonatomic) BOOL hasInitialRootViewController;
|
||||||
@property (nonatomic) BOOL areVersionMigrationsComplete;
|
@property (nonatomic) BOOL areVersionMigrationsComplete;
|
||||||
@property (nonatomic) BOOL didAppLaunchFail;
|
@property (nonatomic) BOOL didAppLaunchFail;
|
||||||
@property (nonatomic) LKP2PServer *lokiP2PServer; // Loki
|
@property (nonatomic) LKP2PServer *lokiP2PServer;
|
||||||
|
@property (nonatomic) LKGroupChatPoller *lokiPublicChatPoller;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
|
@ -758,7 +759,7 @@ static NSTimeInterval launchStartedAt;
|
||||||
[Environment.shared.contactsManager fetchSystemContactsOnceIfAlreadyAuthorized];
|
[Environment.shared.contactsManager fetchSystemContactsOnceIfAlreadyAuthorized];
|
||||||
|
|
||||||
// Loki: Start long polling
|
// Loki: Start long polling
|
||||||
[LKAPI startLongPollingIfNecessary];
|
[LKAPI startLongPollingIfNeeded];
|
||||||
|
|
||||||
// Loki: Tell our friends that we are online
|
// Loki: Tell our friends that we are online
|
||||||
[LKP2PAPI broadcastOnlineStatus];
|
[LKP2PAPI broadcastOnlineStatus];
|
||||||
|
@ -1357,7 +1358,7 @@ static NSTimeInterval launchStartedAt;
|
||||||
[self.readReceiptManager setAreReadReceiptsEnabled:YES];
|
[self.readReceiptManager setAreReadReceiptsEnabled:YES];
|
||||||
|
|
||||||
// Start long polling
|
// Start long polling
|
||||||
[LKAPI startLongPollingIfNecessary];
|
[LKAPI startLongPollingIfNeeded];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1482,4 +1483,29 @@ static NSTimeInterval launchStartedAt;
|
||||||
OWSLogInfo(@"");
|
OWSLogInfo(@"");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#pragma mark - Loki
|
||||||
|
|
||||||
|
- (void)setUpPublicChatIfNeeded
|
||||||
|
{
|
||||||
|
if (self.lokiPublicChatPoller != nil) { return; }
|
||||||
|
self.lokiPublicChatPoller = [[LKGroupChatPoller alloc] initWithGroup:(NSUInteger)LKGroupChatAPI.publicChatID];
|
||||||
|
BOOL isPublicChatSetUp = [NSUserDefaults.standardUserDefaults boolForKey:@"isPublicChatSetUp"];
|
||||||
|
if (isPublicChatSetUp) { return; }
|
||||||
|
NSString *title = NSLocalizedString(@"Loki Public Chat", @"");
|
||||||
|
NSData *groupID = [[[LKGroupChatAPI.serverURL stringByAppendingString:@"."] stringByAppendingString:@(LKGroupChatAPI.publicChatID).stringValue] dataUsingEncoding:NSUTF8StringEncoding];
|
||||||
|
TSGroupModel *group = [[TSGroupModel alloc] initWithTitle:title memberIds:@[ OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey ] image:nil groupId:groupID];
|
||||||
|
__block TSGroupThread *thread;
|
||||||
|
[OWSPrimaryStorage.dbReadWriteConnection readWriteWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
|
||||||
|
thread = [TSGroupThread getOrCreateThreadWithGroupModel:group transaction:transaction];
|
||||||
|
}];
|
||||||
|
[OWSProfileManager.sharedManager addThreadToProfileWhitelist:thread];
|
||||||
|
[NSUserDefaults.standardUserDefaults setBool:YES forKey:@"isPublicChatSetUp"];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)startPublicChatPollingIfNeeded
|
||||||
|
{
|
||||||
|
[self setUpPublicChatIfNeeded];
|
||||||
|
[self.lokiPublicChatPoller startIfNeeded];
|
||||||
|
}
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
53
Signal/src/Loki/LokiGroupChatPoller.swift
Normal file
53
Signal/src/Loki/LokiGroupChatPoller.swift
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
|
||||||
|
@objc(LKGroupChatPoller)
|
||||||
|
public final class LokiGroupChatPoller : NSObject {
|
||||||
|
private let group: UInt
|
||||||
|
private var timer: Timer? = nil
|
||||||
|
private var hasStarted = false
|
||||||
|
|
||||||
|
private let pollInterval: TimeInterval = 4
|
||||||
|
|
||||||
|
@objc public init(group: UInt) {
|
||||||
|
self.group = group
|
||||||
|
super.init()
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc public func startIfNeeded() {
|
||||||
|
if hasStarted { return }
|
||||||
|
timer = Timer.scheduledTimer(withTimeInterval: pollInterval, repeats: true) { [weak self] _ in self?.poll() }
|
||||||
|
hasStarted = true
|
||||||
|
}
|
||||||
|
|
||||||
|
@objc public func stop() {
|
||||||
|
timer?.invalidate()
|
||||||
|
hasStarted = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private func poll() {
|
||||||
|
let group = self.group
|
||||||
|
let _ = LokiGroupChatAPI.getMessages(for: group).map { messages in
|
||||||
|
messages.reversed().map { message in
|
||||||
|
let id = "\(LokiGroupChatAPI.serverURL).\(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..<endIndex]))"
|
||||||
|
x4.setSource(senderDisplayName)
|
||||||
|
x4.setSourceDevice(OWSDevicePrimaryDeviceId)
|
||||||
|
x4.setContent(try! x3.build().serializedData())
|
||||||
|
OWSPrimaryStorage.shared().dbReadWriteConnection.readWrite { transaction in
|
||||||
|
SSKEnvironment.shared.messageManager.throws_processEnvelope(try! x4.build(), plaintextData: try! x3.build().serializedData(), wasReceivedByUD: false, transaction: transaction)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -221,10 +221,10 @@ final class SeedViewController : OnboardingBaseViewController {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
// Use KVC to access dbConnection even though it's private
|
// Use KVC to access dbConnection even though it's private
|
||||||
let databaseConnection = OWSIdentityManager.shared().value(forKey: "dbConnection") as! YapDatabaseConnection
|
let identityManager = OWSIdentityManager.shared()
|
||||||
|
let databaseConnection = identityManager.value(forKey: "dbConnection") as! YapDatabaseConnection
|
||||||
databaseConnection.setObject(seed.toHexString(), forKey: "LKLokiSeed", inCollection: OWSPrimaryStorageIdentityKeyStoreCollection)
|
databaseConnection.setObject(seed.toHexString(), forKey: "LKLokiSeed", inCollection: OWSPrimaryStorageIdentityKeyStoreCollection)
|
||||||
if seed.count == 16 { seed = seed + seed }
|
if seed.count == 16 { seed = seed + seed }
|
||||||
let identityManager = OWSIdentityManager.shared()
|
|
||||||
identityManager.generateNewIdentityKeyPair(fromSeed: seed) // This also stores it
|
identityManager.generateNewIdentityKeyPair(fromSeed: seed) // This also stores it
|
||||||
let keyPair = identityManager.identityKeyPair()!
|
let keyPair = identityManager.identityKeyPair()!
|
||||||
let hexEncodedPublicKey = keyPair.hexEncodedPublicKey
|
let hexEncodedPublicKey = keyPair.hexEncodedPublicKey
|
||||||
|
|
|
@ -74,7 +74,9 @@ class ConversationViewItemActions: NSObject {
|
||||||
class func textActions(conversationViewItem: ConversationViewItem, shouldAllowReply: Bool, delegate: MessageActionsDelegate) -> [MenuAction] {
|
class func textActions(conversationViewItem: ConversationViewItem, shouldAllowReply: Bool, delegate: MessageActionsDelegate) -> [MenuAction] {
|
||||||
var actions: [MenuAction] = []
|
var actions: [MenuAction] = []
|
||||||
|
|
||||||
if shouldAllowReply {
|
let isGroup = conversationViewItem.isGroupThread
|
||||||
|
|
||||||
|
if shouldAllowReply && !isGroup {
|
||||||
let replyAction = MessageActionBuilder.reply(conversationViewItem: conversationViewItem, delegate: delegate)
|
let replyAction = MessageActionBuilder.reply(conversationViewItem: conversationViewItem, delegate: delegate)
|
||||||
actions.append(replyAction)
|
actions.append(replyAction)
|
||||||
}
|
}
|
||||||
|
@ -84,8 +86,10 @@ class ConversationViewItemActions: NSObject {
|
||||||
actions.append(copyTextAction)
|
actions.append(copyTextAction)
|
||||||
}
|
}
|
||||||
|
|
||||||
let deleteAction = MessageActionBuilder.deleteMessage(conversationViewItem: conversationViewItem, delegate: delegate)
|
if !isGroup {
|
||||||
actions.append(deleteAction)
|
let deleteAction = MessageActionBuilder.deleteMessage(conversationViewItem: conversationViewItem, delegate: delegate)
|
||||||
|
actions.append(deleteAction)
|
||||||
|
}
|
||||||
|
|
||||||
let showDetailsAction = MessageActionBuilder.showDetails(conversationViewItem: conversationViewItem, delegate: delegate)
|
let showDetailsAction = MessageActionBuilder.showDetails(conversationViewItem: conversationViewItem, delegate: delegate)
|
||||||
actions.append(showDetailsAction)
|
actions.append(showDetailsAction)
|
||||||
|
|
|
@ -97,8 +97,10 @@ public class ConversationHeaderView: UIStackView {
|
||||||
self.addArrangedSubview(avatarView)
|
self.addArrangedSubview(avatarView)
|
||||||
self.addArrangedSubview(textRows)
|
self.addArrangedSubview(textRows)
|
||||||
|
|
||||||
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapView))
|
if (!thread.isGroupThread()) {
|
||||||
self.addGestureRecognizer(tapGesture)
|
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapView))
|
||||||
|
self.addGestureRecognizer(tapGesture)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
required public init(coder: NSCoder) {
|
required public init(coder: NSCoder) {
|
||||||
|
|
|
@ -1601,7 +1601,9 @@ typedef enum : NSUInteger {
|
||||||
}]];
|
}]];
|
||||||
|
|
||||||
|
|
||||||
self.headerView.attributedSubtitle = subtitleText;
|
if (!self.thread.isGroupThread) {
|
||||||
|
self.headerView.attributedSubtitle = subtitleText;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#pragma mark - Updating
|
#pragma mark - Updating
|
||||||
|
|
|
@ -690,6 +690,10 @@ typedef NS_ENUM(NSInteger, HomeViewControllerSection) {
|
||||||
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", @"") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { /* Do nothing */ }]];
|
[alert addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", @"") style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) { /* Do nothing */ }]];
|
||||||
[self presentAlert:alert];
|
[self presentAlert:alert];
|
||||||
}
|
}
|
||||||
|
if (OWSIdentityManager.sharedManager.identityKeyPair != nil) {
|
||||||
|
AppDelegate *appDelegate = (AppDelegate *)UIApplication.sharedApplication.delegate;
|
||||||
|
[appDelegate startPublicChatPollingIfNeeded];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)applyDefaultBackButton
|
- (void)applyDefaultBackButton
|
||||||
|
|
|
@ -2606,3 +2606,4 @@
|
||||||
"Cancel" = "Cancel";
|
"Cancel" = "Cancel";
|
||||||
"Update Required" = "Update Required";
|
"Update Required" = "Update Required";
|
||||||
"This version of Loki Messenger is no longer supported. Please press OK to reset your account and migrate to the latest version." = "This version of Loki Messenger is no longer supported. Please press OK to reset your account and migrate to the latest version.";
|
"This version of Loki Messenger is no longer supported. Please press OK to reset your account and migrate to the latest version." = "This version of Loki Messenger is no longer supported. Please press OK to reset your account and migrate to the latest version.";
|
||||||
|
"Loki Public Chat" = "Loki Public Chat";
|
||||||
|
|
|
@ -605,12 +605,6 @@ typedef void (^ProfileManagerFailureBlock)(NSError *error);
|
||||||
uint8_t byte = (uint8_t)(0xff & byteValue);
|
uint8_t byte = (uint8_t)(0xff & byteValue);
|
||||||
[groupId appendBytes:&byte length:1];
|
[groupId appendBytes:&byte length:1];
|
||||||
}
|
}
|
||||||
if (groupId.length != (NSUInteger)kGroupIdLength) {
|
|
||||||
OWSFailDebug(@"Parsed group id has unexpected length: %@ (%lu)",
|
|
||||||
groupId.hexadecimalString,
|
|
||||||
(unsigned long)groupId.length);
|
|
||||||
return nil;
|
|
||||||
}
|
|
||||||
return [groupId copy];
|
return [groupId copy];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -185,7 +185,7 @@ typedef void (^BuildOutgoingMessageCompletionBlock)(TSOutgoingMessage *savedMess
|
||||||
|
|
||||||
// Loki: If we're not friends then always set the message to a friend request message
|
// Loki: If we're not friends then always set the message to a friend request message
|
||||||
// If we're friends then the assumption is that we have the other user's prekey bundle
|
// If we're friends then the assumption is that we have the other user's prekey bundle
|
||||||
NSString *messageClassAsString = thread.isContactFriend ? @"TSOutgoingMessage" : @"LKFriendRequestMessage";
|
NSString *messageClassAsString = (thread.isContactFriend || thread.isGroupThread) ? @"TSOutgoingMessage" : @"LKFriendRequestMessage";
|
||||||
Class messageClass = NSClassFromString(messageClassAsString);
|
Class messageClass = NSClassFromString(messageClassAsString);
|
||||||
|
|
||||||
TSOutgoingMessage *message =
|
TSOutgoingMessage *message =
|
||||||
|
|
|
@ -10,7 +10,7 @@ public extension LokiAPI {
|
||||||
|
|
||||||
/// Start long polling.
|
/// Start long polling.
|
||||||
/// This will send a notification if new messages were received
|
/// This will send a notification if new messages were received
|
||||||
@objc public static func startLongPollingIfNecessary() {
|
@objc public static func startLongPollingIfNeeded() {
|
||||||
guard !isLongPolling else { return }
|
guard !isLongPolling else { return }
|
||||||
isLongPolling = true
|
isLongPolling = true
|
||||||
shouldStopPolling = false
|
shouldStopPolling = false
|
||||||
|
|
|
@ -48,6 +48,7 @@ public final class LokiGroupChatAPI : NSObject {
|
||||||
print("[Loki] Couldn't parse message for group chat with ID: \(group) from: \(message).")
|
print("[Loki] Couldn't parse message for group chat with ID: \(group) from: \(message).")
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
guard hexEncodedPublicKey != userHexEncodedPublicKey else { return nil }
|
||||||
return LokiGroupMessage(serverID: serverID, hexEncodedPublicKey: hexEncodedPublicKey, displayName: displayName, body: body, type: publicChatMessageType, timestamp: timestamp)
|
return LokiGroupMessage(serverID: serverID, hexEncodedPublicKey: hexEncodedPublicKey, displayName: displayName, body: body, type: publicChatMessageType, timestamp: timestamp)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@ import PromiseKit
|
||||||
|
|
||||||
@objc(LKGroupMessage)
|
@objc(LKGroupMessage)
|
||||||
public final class LokiGroupMessage : NSObject {
|
public final class LokiGroupMessage : NSObject {
|
||||||
let serverID: UInt?
|
public let serverID: UInt?
|
||||||
let hexEncodedPublicKey: String
|
public let hexEncodedPublicKey: String
|
||||||
let displayName: String
|
public let displayName: String
|
||||||
let body: String
|
public let body: String
|
||||||
/// - Note: Expressed as milliseconds since 00:00:00 UTC on 1 January 1970.
|
/// - Note: Expressed as milliseconds since 00:00:00 UTC on 1 January 1970.
|
||||||
let timestamp: UInt64
|
public let timestamp: UInt64
|
||||||
let type: String
|
public let type: String
|
||||||
|
|
||||||
public init(serverID: UInt?, hexEncodedPublicKey: String, displayName: String, body: String, type: String, timestamp: UInt64) {
|
public init(serverID: UInt?, hexEncodedPublicKey: String, displayName: String, body: String, type: String, timestamp: UInt64) {
|
||||||
self.serverID = serverID
|
self.serverID = serverID
|
||||||
|
@ -24,7 +24,7 @@ public final class LokiGroupMessage : NSObject {
|
||||||
self.init(serverID: nil, hexEncodedPublicKey: hexEncodedPublicKey, displayName: displayName, body: body, type: type, timestamp: timestamp)
|
self.init(serverID: nil, hexEncodedPublicKey: hexEncodedPublicKey, displayName: displayName, body: body, type: type, timestamp: timestamp)
|
||||||
}
|
}
|
||||||
|
|
||||||
public func toJSON() -> JSON {
|
internal func toJSON() -> JSON {
|
||||||
let value: JSON = [ "timestamp" : timestamp, "from" : displayName, "source" : hexEncodedPublicKey ]
|
let value: JSON = [ "timestamp" : timestamp, "from" : displayName, "source" : hexEncodedPublicKey ]
|
||||||
return [ "text" : body, "annotations": [ [ "type" : type, "value" : value ] ] ]
|
return [ "text" : body, "annotations": [ [ "type" : type, "value" : value ] ] ]
|
||||||
}
|
}
|
||||||
|
|
|
@ -259,7 +259,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
OWSLogInfo(@"handling decrypted envelope: %@", [self descriptionForEnvelope:envelope]);
|
OWSLogInfo(@"handling decrypted envelope: %@", [self descriptionForEnvelope:envelope]);
|
||||||
|
|
||||||
if (!envelope.hasSource || envelope.source.length < 1 || ![ECKeyPair isValidHexEncodedPublicKeyWithCandidate:envelope.source]) {
|
if (!envelope.hasSource || envelope.source.length < 1) {
|
||||||
OWSFailDebug(@"incoming envelope has invalid source");
|
OWSFailDebug(@"incoming envelope has invalid source");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -500,26 +500,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
||||||
if ([message isKindOfClass:[OWSOutgoingSyncMessage class]]) {
|
if ([message isKindOfClass:[OWSOutgoingSyncMessage class]]) {
|
||||||
[recipientIds addObject:self.tsAccountManager.localNumber];
|
[recipientIds addObject:self.tsAccountManager.localNumber];
|
||||||
} else if (thread.isGroupThread) {
|
} else if (thread.isGroupThread) {
|
||||||
TSGroupThread *groupThread = (TSGroupThread *)thread;
|
[recipientIds addObject:LKGroupChatAPI.serverURL];
|
||||||
|
|
||||||
// Send to the intersection of:
|
|
||||||
//
|
|
||||||
// * "sending" recipients of the message.
|
|
||||||
// * members of the group.
|
|
||||||
//
|
|
||||||
// I.e. try to send a message IFF:
|
|
||||||
//
|
|
||||||
// * The recipient was in the group when the message was first tried to be sent.
|
|
||||||
// * The recipient is still in the group.
|
|
||||||
// * The recipient is in the "sending" state.
|
|
||||||
|
|
||||||
[recipientIds addObjectsFromArray:message.sendingRecipientIds];
|
|
||||||
// Only send to members in the latest known group member list.
|
|
||||||
[recipientIds intersectSet:[NSSet setWithArray:groupThread.groupModel.groupMemberIds]];
|
|
||||||
|
|
||||||
if ([recipientIds containsObject:self.tsAccountManager.localNumber]) {
|
|
||||||
OWSFailDebug(@"Message send recipients should not include self.");
|
|
||||||
}
|
|
||||||
} else if ([thread isKindOfClass:[TSContactThread class]]) {
|
} else if ([thread isKindOfClass:[TSContactThread class]]) {
|
||||||
NSString *recipientContactId = ((TSContactThread *)thread).contactIdentifier;
|
NSString *recipientContactId = ((TSContactThread *)thread).contactIdentifier;
|
||||||
|
|
||||||
|
@ -974,8 +955,12 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
||||||
}
|
}
|
||||||
|
|
||||||
NSError *deviceMessagesError;
|
NSError *deviceMessagesError;
|
||||||
NSArray<NSDictionary *> *_Nullable deviceMessages =
|
NSArray<NSDictionary *> *_Nullable deviceMessages;
|
||||||
[self deviceMessagesForMessageSend:messageSend error:&deviceMessagesError];
|
if (!message.thread.isGroupThread) {
|
||||||
|
deviceMessages = [self deviceMessagesForMessageSend:messageSend error:&deviceMessagesError];
|
||||||
|
} else {
|
||||||
|
deviceMessages = @{};
|
||||||
|
}
|
||||||
if (deviceMessagesError || !deviceMessages) {
|
if (deviceMessagesError || !deviceMessages) {
|
||||||
OWSAssertDebug(deviceMessagesError);
|
OWSAssertDebug(deviceMessagesError);
|
||||||
return messageSend.failure(deviceMessagesError);
|
return messageSend.failure(deviceMessagesError);
|
||||||
|
@ -1081,7 +1066,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (deviceMessages.count == 0) {
|
if (deviceMessages.count == 0 && !message.thread.isGroupThread) {
|
||||||
// This might happen:
|
// This might happen:
|
||||||
//
|
//
|
||||||
// * The first (after upgrading?) time we send a sync message to our linked devices.
|
// * The first (after upgrading?) time we send a sync message to our linked devices.
|
||||||
|
@ -1117,14 +1102,14 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
||||||
OWSFailDebug(@"Missing underlying error: %@.", error);
|
OWSFailDebug(@"Missing underlying error: %@.", error);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
OWSFailDebug(@"Unexpected error: %@.", error);
|
//OWSFailDebug(@"Unexpected error: %@.", error);
|
||||||
}
|
}
|
||||||
[self messageSendDidFail:messageSend deviceMessages:deviceMessages statusCode:statusCode error:error responseData:responseData];
|
[self messageSendDidFail:messageSend deviceMessages:deviceMessages statusCode:statusCode error:error responseData:responseData];
|
||||||
};
|
};
|
||||||
|
|
||||||
if ([recipient.recipientId isEqualToString:LKGroupChatAPI.serverURL]) {
|
if ([recipient.recipientId isEqualToString:LKGroupChatAPI.serverURL]) {
|
||||||
NSString *userHexEncodedPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey;
|
NSString *userHexEncodedPublicKey = OWSIdentityManager.sharedManager.identityKeyPair.hexEncodedPublicKey;
|
||||||
NSString *displayName = [SSKEnvironment.shared.contactsManager displayNameForPhoneIdentifier:userHexEncodedPublicKey];
|
NSString *displayName = @"Anonymous";
|
||||||
if (displayName == nil) { displayName = @"Anonymous"; }
|
if (displayName == nil) { displayName = @"Anonymous"; }
|
||||||
LKGroupMessage *groupMessage = [[LKGroupMessage alloc] initWithHexEncodedPublicKey:userHexEncodedPublicKey displayName:displayName body:message.body type:LKGroupChatAPI.publicChatMessageType timestamp:message.timestamp];
|
LKGroupMessage *groupMessage = [[LKGroupMessage alloc] initWithHexEncodedPublicKey:userHexEncodedPublicKey displayName:displayName body:message.body type:LKGroupChatAPI.publicChatMessageType timestamp:message.timestamp];
|
||||||
[[LKGroupChatAPI sendMessage:groupMessage toGroup:LKGroupChatAPI.publicChatID]
|
[[LKGroupChatAPI sendMessage:groupMessage toGroup:LKGroupChatAPI.publicChatID]
|
||||||
|
|
|
@ -27,7 +27,6 @@ const int32_t kGroupIdLength = 16;
|
||||||
groupId:(NSData *)groupId
|
groupId:(NSData *)groupId
|
||||||
{
|
{
|
||||||
OWSAssertDebug(memberIds);
|
OWSAssertDebug(memberIds);
|
||||||
OWSAssertDebug(groupId.length == kGroupIdLength);
|
|
||||||
|
|
||||||
_groupName = title;
|
_groupName = title;
|
||||||
_groupMemberIds = [memberIds copy];
|
_groupMemberIds = [memberIds copy];
|
||||||
|
@ -49,7 +48,6 @@ const int32_t kGroupIdLength = 16;
|
||||||
if (_groupMemberIds == nil) {
|
if (_groupMemberIds == nil) {
|
||||||
_groupMemberIds = [NSArray new];
|
_groupMemberIds = [NSArray new];
|
||||||
}
|
}
|
||||||
OWSAssertDebug(self.groupId.length == kGroupIdLength);
|
|
||||||
|
|
||||||
return self;
|
return self;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue