use server time to order open group messages
This commit is contained in:
parent
449402804c
commit
409337b512
|
@ -122,10 +122,12 @@ public final class PublicChatAPI : DotNetAPI {
|
|||
return rawMessages.flatMap { message in
|
||||
let isDeleted = (message["is_deleted"] as? Int == 1)
|
||||
guard !isDeleted else { return nil }
|
||||
let dateFormatter = DateFormatter()
|
||||
dateFormatter.dateFormat = "yyyy-MM-dd'T'HH:mm:ss.SSSZ"
|
||||
guard let annotations = message["annotations"] as? [JSON], let annotation = annotations.first(where: { $0["type"] as? String == publicChatMessageType }), let value = annotation["value"] as? JSON,
|
||||
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 {
|
||||
let timestamp = value["timestamp"] as? UInt64, let dateAsString = message["created_at"] as? String, let date = dateFormatter.date(from: dateAsString) else {
|
||||
print("[Loki] Couldn't parse message for public chat channel with ID: \(channel) on server: \(server) from: \(message).")
|
||||
return nil
|
||||
}
|
||||
|
@ -168,7 +170,7 @@ public final class PublicChatAPI : DotNetAPI {
|
|||
width: width, height: height, caption: caption, url: url, linkPreviewURL: linkPreviewURL, linkPreviewTitle: linkPreviewTitle)
|
||||
}
|
||||
let result = PublicChatMessage(serverID: serverID, senderPublicKey: hexEncodedPublicKey, displayName: displayName, profilePicture: profilePicture,
|
||||
body: body, type: publicChatMessageType, timestamp: timestamp, quote: quote, attachments: attachments, signature: signature)
|
||||
body: body, type: publicChatMessageType, timestamp: timestamp, quote: quote, attachments: attachments, signature: signature, serverTime: date)
|
||||
guard result.hasValidSignature() else {
|
||||
print("[Loki] Ignoring public chat message with invalid signature.")
|
||||
return nil
|
||||
|
@ -182,7 +184,7 @@ public final class PublicChatAPI : DotNetAPI {
|
|||
return nil
|
||||
}
|
||||
return result
|
||||
}.sorted { $0.timestamp < $1.timestamp }
|
||||
}.sorted { $0.serverTime!.compare($1.serverTime!) == ComparisonResult.orderedAscending }
|
||||
}
|
||||
}
|
||||
}.handlingInvalidAuthTokenIfNeeded(for: server)
|
||||
|
@ -217,7 +219,7 @@ public final class PublicChatAPI : DotNetAPI {
|
|||
throw DotNetAPIError.parsingFailed
|
||||
}
|
||||
let timestamp = UInt64(date.timeIntervalSince1970) * 1000
|
||||
return PublicChatMessage(serverID: serverID, senderPublicKey: getUserHexEncodedPublicKey(), displayName: displayName, profilePicture: signedMessage.profilePicture, body: body, type: publicChatMessageType, timestamp: timestamp, quote: signedMessage.quote, attachments: signedMessage.attachments, signature: signedMessage.signature)
|
||||
return PublicChatMessage(serverID: serverID, senderPublicKey: getUserHexEncodedPublicKey(), displayName: displayName, profilePicture: signedMessage.profilePicture, body: body, type: publicChatMessageType, timestamp: timestamp, quote: signedMessage.quote, attachments: signedMessage.attachments, signature: signedMessage.signature, serverTime: date)
|
||||
}
|
||||
}
|
||||
}.handlingInvalidAuthTokenIfNeeded(for: server)
|
||||
|
|
|
@ -14,6 +14,9 @@ public final class PublicChatMessage : NSObject {
|
|||
public var attachments: [Attachment] = []
|
||||
public let signature: Signature?
|
||||
|
||||
// MARK: Server Time (use for sorting)
|
||||
public let serverTime: Date?
|
||||
|
||||
@objc(serverID)
|
||||
public var objc_serverID: UInt64 { return serverID ?? 0 }
|
||||
|
||||
|
@ -72,7 +75,7 @@ public final class PublicChatMessage : NSObject {
|
|||
}
|
||||
|
||||
// MARK: Initialization
|
||||
public init(serverID: UInt64?, senderPublicKey: String, displayName: String, profilePicture: ProfilePicture?, body: String, type: String, timestamp: UInt64, quote: Quote?, attachments: [Attachment], signature: Signature?) {
|
||||
public init(serverID: UInt64?, senderPublicKey: String, displayName: String, profilePicture: ProfilePicture?, body: String, type: String, timestamp: UInt64, quote: Quote?, attachments: [Attachment], signature: Signature?, serverTime: Date? = nil) {
|
||||
self.serverID = serverID
|
||||
self.senderPublicKey = senderPublicKey
|
||||
self.displayName = displayName
|
||||
|
@ -83,10 +86,11 @@ public final class PublicChatMessage : NSObject {
|
|||
self.quote = quote
|
||||
self.attachments = attachments
|
||||
self.signature = signature
|
||||
self.serverTime = serverTime
|
||||
super.init()
|
||||
}
|
||||
|
||||
@objc public convenience init(senderPublicKey: String, displayName: String, body: String, type: String, timestamp: UInt64, quotedMessageTimestamp: UInt64, quoteePublicKey: String?, quotedMessageBody: String?, quotedMessageServerID: UInt64, signatureData: Data?, signatureVersion: UInt64) {
|
||||
@objc public convenience init(senderPublicKey: String, displayName: String, body: String, type: String, timestamp: UInt64, quotedMessageTimestamp: UInt64, quoteePublicKey: String?, quotedMessageBody: String?, quotedMessageServerID: UInt64, signatureData: Data?, signatureVersion: UInt64, serverTime: Date? = nil) {
|
||||
let quote: Quote?
|
||||
if quotedMessageTimestamp != 0, let quoteeHexEncodedPublicKey = quoteePublicKey, let quotedMessageBody = quotedMessageBody {
|
||||
let quotedMessageServerID = (quotedMessageServerID != 0) ? quotedMessageServerID : nil
|
||||
|
@ -100,7 +104,7 @@ public final class PublicChatMessage : NSObject {
|
|||
} else {
|
||||
signature = nil
|
||||
}
|
||||
self.init(serverID: nil, senderPublicKey: senderPublicKey, displayName: displayName, profilePicture: nil, body: body, type: type, timestamp: timestamp, quote: quote, attachments: [], signature: signature)
|
||||
self.init(serverID: nil, senderPublicKey: senderPublicKey, displayName: displayName, profilePicture: nil, body: body, type: type, timestamp: timestamp, quote: quote, attachments: [], signature: signature, serverTime: serverTime)
|
||||
}
|
||||
|
||||
// MARK: Crypto
|
||||
|
@ -115,7 +119,7 @@ public final class PublicChatMessage : NSObject {
|
|||
return nil
|
||||
}
|
||||
let signature = Signature(data: signatureData, version: signatureVersion)
|
||||
return PublicChatMessage(serverID: serverID, senderPublicKey: senderPublicKey, displayName: displayName, profilePicture: profilePicture, body: body, type: type, timestamp: timestamp, quote: quote, attachments: attachments, signature: signature)
|
||||
return PublicChatMessage(serverID: serverID, senderPublicKey: senderPublicKey, displayName: displayName, profilePicture: profilePicture, body: body, type: type, timestamp: timestamp, quote: quote, attachments: attachments, signature: signature, serverTime: serverTime)
|
||||
}
|
||||
|
||||
internal func hasValidSignature() -> Bool {
|
||||
|
|
|
@ -75,7 +75,7 @@ public final class PublicChatPoller : NSObject {
|
|||
}
|
||||
*/
|
||||
// Sorting the messages by timestamp before importing them fixes an issue where messages that quote older messages can't find those older messages
|
||||
messages.sorted { $0.timestamp < $1.timestamp }.forEach { message in
|
||||
messages.sorted { $0.serverTime!.compare($1.serverTime!) == ComparisonResult.orderedAscending }.forEach { message in
|
||||
var wasSentByCurrentUser = false
|
||||
OWSPrimaryStorage.shared().dbReadConnection.read { transaction in
|
||||
wasSentByCurrentUser = LokiDatabaseUtilities.isUserLinkedDevice(message.senderPublicKey, transaction: transaction)
|
||||
|
|
|
@ -1043,7 +1043,7 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
|
|||
}
|
||||
NSString *body = (message.body != nil && message.body.length > 0) ? message.body : [NSString stringWithFormat:@"%@", @(message.timestamp)]; // Workaround for the fact that the back-end doesn't accept messages without a body
|
||||
LKPublicChatMessage *groupMessage = [[LKPublicChatMessage alloc] initWithSenderPublicKey:userPublicKey displayName:displayName body:body type:LKPublicChatAPI.publicChatMessageType
|
||||
timestamp:message.timestamp quotedMessageTimestamp:quoteID quoteePublicKey:quoteePublicKey quotedMessageBody:quote.body quotedMessageServerID:quotedMessageServerID signatureData:nil signatureVersion:0];
|
||||
timestamp:message.timestamp quotedMessageTimestamp:quoteID quoteePublicKey:quoteePublicKey quotedMessageBody:quote.body quotedMessageServerID:quotedMessageServerID signatureData:nil signatureVersion:0 serverTime:nil];
|
||||
OWSLinkPreview *linkPreview = message.linkPreview;
|
||||
if (linkPreview != nil) {
|
||||
TSAttachmentStream *attachment = [TSAttachmentStream fetchObjectWithUniqueID:linkPreview.imageAttachmentId];
|
||||
|
|
Loading…
Reference in New Issue