Fix remaining TODOs

This commit is contained in:
Niels Andriesse 2020-12-07 15:11:49 +11:00
parent 61611db58e
commit 3f5bc18f6b
15 changed files with 216 additions and 46 deletions

View File

@ -1454,9 +1454,9 @@ typedef enum : NSUInteger {
// Do nothing
}
- (void)handleUnsentMessageTap:(TSOutgoingMessage *)message
- (void)handleUnsentMessageTap:(TSOutgoingMessage *)tsMessage
{
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:message.mostRecentFailureText
UIAlertController *actionSheet = [UIAlertController alertControllerWithTitle:tsMessage.mostRecentFailureText
message:nil
preferredStyle:UIAlertControllerStyleActionSheet];
@ -1465,23 +1465,29 @@ typedef enum : NSUInteger {
UIAlertAction *deleteMessageAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"TXT_DELETE_TITLE", @"")
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *action) {
[self remove:message];
[self remove:tsMessage];
}];
[actionSheet addAction:deleteMessageAction];
// TODO TODO TODO
UIAlertAction *resendMessageAction = [UIAlertAction
actionWithTitle:NSLocalizedString(@"SEND_AGAIN_BUTTON", @"")
accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME(self, @"send_again")
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
SNVisibleMessage *message = [SNVisibleMessage from:tsMessage];
[LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
NSMutableArray<TSAttachmentStream *> *attachments = @[].mutableCopy;
for (NSString *attachmentID in tsMessage.attachmentIds) {
TSAttachmentStream *stream = [TSAttachmentStream fetchObjectWithUniqueID:attachmentID transaction:transaction];
if (![stream isKindOfClass:TSAttachmentStream.class]) { continue; }
[attachments addObject:stream];
}
[SNMessageSender prep:attachments forMessage:message usingTransaction: transaction];
[SNMessageSender send:message inThread:self.thread usingTransaction:transaction];
}];
}];
// UIAlertAction *resendMessageAction = [UIAlertAction
// actionWithTitle:NSLocalizedString(@"SEND_AGAIN_BUTTON", @"")
// accessibilityIdentifier:ACCESSIBILITY_IDENTIFIER_WITH_NAME(self, @"send_again")
// style:UIAlertActionStyleDefault
// handler:^(UIAlertAction *action) {
// [LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *_Nonnull transaction) {
// [self.messageSenderJobQueue addMessage:message transaction:transaction];
// }];
// }];
// [actionSheet addAction:resendMessageAction];
[actionSheet addAction:resendMessageAction];
[self dismissKeyBoard];
[self presentAlert:actionSheet];

View File

@ -6,11 +6,20 @@ public final class ClosedGroupUpdate : ControlMessage {
public var kind: Kind?
// MARK: Kind
public enum Kind {
public enum Kind : CustomStringConvertible {
case new(groupPublicKey: Data, name: String, groupPrivateKey: Data, senderKeys: [ClosedGroupSenderKey], members: [Data], admins: [Data])
case info(groupPublicKey: Data, name: String, senderKeys: [ClosedGroupSenderKey], members: [Data], admins: [Data])
case senderKeyRequest(groupPublicKey: Data)
case senderKey(groupPublicKey: Data, senderKey: ClosedGroupSenderKey)
public var description: String {
switch self {
case .new: return "new"
case .info: return "info"
case .senderKeyRequest: return "senderKeyRequest"
case .senderKey: return "senderKey"
}
}
}
// MARK: Initialization
@ -154,6 +163,15 @@ public final class ClosedGroupUpdate : ControlMessage {
return nil
}
}
// MARK: Description
public override var description: String {
"""
ClosedGroupUpdate(
kind: \(kind?.description ?? "null")
)
"""
}
}
private extension ClosedGroupSenderKey {

View File

@ -56,6 +56,15 @@ public final class ExpirationTimerUpdate : ControlMessage {
}
}
// MARK: Description
public override var description: String {
"""
ExpirationTimerUpdate(
duration: \(duration?.description ?? "null")
)
"""
}
// MARK: Convenience
@objc public func setDuration(_ duration: UInt32) {
self.duration = duration

View File

@ -54,4 +54,13 @@ public final class ReadReceipt : ControlMessage {
return nil
}
}
// MARK: Description
public override var description: String {
"""
ReadReceipt(
timestamps: \(timestamps?.description ?? "null")
)
"""
}
}

View File

@ -7,7 +7,7 @@ public final class TypingIndicator : ControlMessage {
public override class var ttl: UInt64 { 30 * 1000 }
// MARK: Kind
public enum Kind : Int {
public enum Kind : Int, CustomStringConvertible {
case started, stopped
static func fromProto(_ proto: SNProtoTypingMessage.SNProtoTypingMessageAction) -> Kind {
@ -23,6 +23,13 @@ public final class TypingIndicator : ControlMessage {
case .stopped: return .stopped
}
}
public var description: String {
switch self {
case .started: return "started"
case .stopped: return "stopped"
}
}
}
// MARK: Validation
@ -72,4 +79,13 @@ public final class TypingIndicator : ControlMessage {
return nil
}
}
// MARK: Description
public override var description: String {
"""
TypingIndicator(
kind: \(kind?.description ?? "null")
)
"""
}
}

View File

@ -1,3 +1,4 @@
import SessionUtilitiesKit
@objc public extension TSOutgoingMessage {
@ -21,3 +22,23 @@
)
}
}
@objc public extension VisibleMessage {
@objc(from:)
static func from(_ tsMessage: TSOutgoingMessage) -> VisibleMessage {
let result = VisibleMessage()
result.threadID = tsMessage.uniqueThreadId
result.sentTimestamp = tsMessage.timestamp
result.recipient = tsMessage.recipientIds().first
if let thread = tsMessage.thread as? TSGroupThread, thread.usesSharedSenderKeys {
let groupID = thread.groupModel.groupId
result.groupPublicKey = LKGroupUtilities.getDecodedGroupID(groupID)
}
result.text = tsMessage.body
result.attachmentIDs = tsMessage.attachmentIds.compactMap { $0 as? String }
result.quote = VisibleMessage.Quote.from(tsMessage.quotedMessage)
result.linkPreview = VisibleMessage.LinkPreview.from(tsMessage.linkPreview)
return result
}
}

View File

@ -56,5 +56,16 @@ public extension VisibleMessage {
return nil
}
}
// MARK: Description
public override var description: String {
"""
LinkPreview(
title: \(title ?? "null")
url: \(url ?? "null")
attachmentID: \(attachmentID ?? "null")
)
"""
}
}
}

View File

@ -57,5 +57,16 @@ public extension VisibleMessage {
return nil
}
}
// MARK: Description
public override var description: String {
"""
Profile(
displayName: \(displayName ?? "null")
profileKey: \(profileKey?.description ?? "null")
profilePictureURL: \(profilePictureURL ?? "null")
)
"""
}
}
}

View File

@ -66,8 +66,9 @@ public extension VisibleMessage {
guard let stream = TSAttachmentStream.fetch(uniqueId: attachmentID, transaction: transaction), stream.isUploaded else {
#if DEBUG
preconditionFailure("Sending a message before all associated attachments have been uploaded.")
#endif
#else
return
#endif
}
let quotedAttachmentProto = SNProtoDataMessageQuoteQuotedAttachment.builder()
quotedAttachmentProto.setContentType(stream.contentType)
@ -82,5 +83,17 @@ public extension VisibleMessage {
SNLog("Couldn't construct quoted attachment proto from: \(self).")
}
}
// MARK: Description
public override var description: String {
"""
Quote(
timestamp: \(timestamp?.description ?? "null")
publicKey: \(publicKey ?? "null")
text: \(text ?? "null")
attachmentID: \(attachmentID ?? "null")
)
"""
}
}
}

View File

@ -99,4 +99,18 @@ public final class VisibleMessage : Message {
return nil
}
}
// MARK: Description
public override var description: String {
"""
VisibleMessage(
text: \(text ?? "null")
attachmentIDs: \(attachmentIDs)
quote: \(quote?.description ?? "null")
linkPreview: \(linkPreview?.description ?? "null")
contact: \(contact?.description ?? "null")
profile: \(profile?.description ?? "null")
)
"""
}
}

View File

@ -9,6 +9,11 @@ extension OWSLinkPreview {
extension VisibleMessage.LinkPreview {
public static func from(_ linkPreview: OWSLinkPreview?) -> VisibleMessage.LinkPreview? {
guard let linkPreview = linkPreview else { return nil }
return VisibleMessage.LinkPreview(title: linkPreview.title, url: linkPreview.urlString!, attachmentID: linkPreview.imageAttachmentId)
}
@objc(from:using:)
public static func from(_ linkPreview: OWSLinkPreviewDraft?, using transaction: YapDatabaseReadWriteTransaction) -> VisibleMessage.LinkPreview? {
guard let linkPreview = linkPreview else { return nil }

View File

@ -59,6 +59,19 @@ public final class MessageSender : NSObject {
attachment.write($0.dataSource)
attachment.save(with: transaction)
}
prep(attachments, for: message, using: transaction)
}
@objc(prep:forMessage:usingTransaction:)
public static func prep(_ attachmentStreams: [TSAttachmentStream], for message: VisibleMessage, using transaction: YapDatabaseReadWriteTransaction) {
guard let tsMessage = TSOutgoingMessage.find(withTimestamp: message.sentTimestamp!) else {
#if DEBUG
preconditionFailure()
#else
return
#endif
}
var attachments = attachmentStreams
// The line below locally generates a thumbnail for the quoted attachment. It just needs to happen at some point during the
// message sending process.
tsMessage.quotedMessage?.createThumbnailAttachmentsIfNecessary(with: transaction)
@ -71,6 +84,7 @@ public final class MessageSender : NSObject {
// Anything added to message.attachmentIDs will be uploaded by an UploadAttachmentJob. Any attachment IDs added to tsMessage will
// make it render as an attachment (not what we want in the case of a link preview or quoted attachment).
message.attachmentIDs = attachments.map { $0.uniqueId! }
tsMessage.attachmentIds.removeAllObjects()
tsMessage.attachmentIds.addObjects(from: message.attachmentIDs)
if let id = linkPreviewAttachmentID { tsMessage.attachmentIds.remove(id) }
tsMessage.save(with: transaction)
@ -109,7 +123,9 @@ public final class MessageSender : NSObject {
func handleFailure(with error: Swift.Error, using transaction: YapDatabaseReadWriteTransaction) {
MessageSender.handleFailedMessageSend(message, with: error, using: transaction)
if case .contact(_) = destination, message is VisibleMessage, !isSelfSend {
NotificationCenter.default.post(name: .messageSendingFailed, object: NSNumber(value: message.sentTimestamp!))
DispatchQueue.main.async {
NotificationCenter.default.post(name: .messageSendingFailed, object: NSNumber(value: message.sentTimestamp!))
}
}
seal.reject(error)
}
@ -217,7 +233,9 @@ public final class MessageSender : NSObject {
guard !isSuccess else { return } // Succeed as soon as the first promise succeeds
isSuccess = true
if case .contact(_) = destination, message is VisibleMessage, !isSelfSend {
NotificationCenter.default.post(name: .messageSent, object: NSNumber(value: message.sentTimestamp!))
DispatchQueue.main.async {
NotificationCenter.default.post(name: .messageSent, object: NSNumber(value: message.sentTimestamp!))
}
}
storage.withAsync({ transaction in
MessageSender.handleSuccessfulMessageSend(message, to: destination, using: transaction)

View File

@ -16,3 +16,16 @@ extension TSQuotedMessage {
)
}
}
extension VisibleMessage.Quote {
public static func from(_ quote: TSQuotedMessage?) -> VisibleMessage.Quote? {
guard let quote = quote else { return nil }
let result = VisibleMessage.Quote()
result.timestamp = quote.timestamp
result.publicKey = quote.authorId
result.text = quote.body
result.attachmentID = quote.quotedAttachments.first?.attachmentId
return result
}
}

View File

@ -22,6 +22,11 @@ extension MessageSender {
return AnyPromise.from(sendNonDurably(message, with: attachments, in: thread, using: transaction))
}
@objc(sendNonDurably:withAttachmentIDs:inThread:usingTransaction:)
public static func objc_sendNonDurably(_ message: VisibleMessage, with attachmentIDs: [String], in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) -> AnyPromise {
return AnyPromise.from(sendNonDurably(message, with: attachmentIDs, in: thread, using: transaction))
}
@objc(sendNonDurably:inThread:usingTransaction:)
public static func objc_sendNonDurably(_ message: Message, in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) -> AnyPromise {
return AnyPromise.from(sendNonDurably(message, in: thread, using: transaction))
@ -29,7 +34,11 @@ extension MessageSender {
public static func sendNonDurably(_ message: VisibleMessage, with attachments: [SignalAttachment], in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) -> Promise<Void> {
prep(attachments, for: message, using: transaction)
let attachments = message.attachmentIDs.compactMap { TSAttachmentStream.fetch(uniqueId: $0, transaction: transaction) }
return sendNonDurably(message, with: message.attachmentIDs, in: thread, using: transaction)
}
public static func sendNonDurably(_ message: VisibleMessage, with attachmentIDs: [String], in thread: TSThread, using transaction: YapDatabaseReadWriteTransaction) -> Promise<Void> {
let attachments = attachmentIDs.compactMap { TSAttachmentStream.fetch(uniqueId: $0, transaction: transaction) }
let attachmentsToUpload = attachments.filter { !$0.isUploaded }
let attachmentUploadPromises: [Promise<Void>] = attachmentsToUpload.map { stream in
let openGroup = SNMessagingKitConfiguration.shared.storage.getOpenGroup(for: thread.uniqueId!)

View File

@ -414,10 +414,10 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
});
}
- (void)resendMessage:(TSOutgoingMessage *)message fromViewController:(UIViewController *)fromViewController
- (void)resendMessage:(TSOutgoingMessage *)tsMessage fromViewController:(UIViewController *)fromViewController
{
OWSAssertIsOnMainThread();
OWSAssertDebug(message);
OWSAssertDebug(tsMessage);
OWSAssertDebug(fromViewController);
NSString *progressTitle = NSLocalizedString(@"SHARE_EXTENSION_SENDING_IN_PROGRESS_TITLE", @"Alert title");
@ -434,29 +434,26 @@ typedef void (^SendMessageBlock)(SendCompletionBlock completion);
[fromViewController
presentAlert:progressAlert
completion:^{
// TODO TODO TODO
// [self.messageSender sendMessage:message
// success:^{
// OWSLogInfo(@"Resending attachment succeeded.");
// dispatch_async(dispatch_get_main_queue(), ^{
// [self.shareViewDelegate shareViewWasCompleted];
// });
// }
// failure:^(NSError *error) {
// dispatch_async(dispatch_get_main_queue(), ^{
// [fromViewController
// dismissViewControllerAnimated:YES
// completion:^{
// OWSLogInfo(@"Sending attachment failed with error: %@", error);
// [self showSendFailureAlertWithError:error
// message:message
// fromViewController:fromViewController];
// }];
// });
// }];
completion:^{
SNVisibleMessage *message = [SNVisibleMessage from:tsMessage];
[LKStorage writeWithBlock:^(YapDatabaseReadWriteTransaction *transaction) {
NSMutableArray<TSAttachmentStream *> *attachments = @[].mutableCopy;
for (NSString *attachmentID in tsMessage.attachmentIds) {
TSAttachmentStream *stream = [TSAttachmentStream fetchObjectWithUniqueID:attachmentID transaction:transaction];
if (![stream isKindOfClass:TSAttachmentStream.class]) { continue; }
[attachments addObject:stream];
}
[SNMessageSender prep:attachments forMessage:message usingTransaction: transaction];
[SNMessageSender sendNonDurably:message withAttachmentIDs:tsMessage.attachmentIds inThread:self.thread usingTransaction:transaction]
.thenOn(dispatch_get_main_queue(), ^() {
[self.shareViewDelegate shareViewWasCompleted];
})
.catchOn(dispatch_get_main_queue(), ^(NSError *error) {
[fromViewController dismissViewControllerAnimated:YES completion:^{
[self showSendFailureAlertWithError:error message:tsMessage fromViewController:fromViewController];
}];
});
}];
}];
}