Rework proto schema changes for quoted replies.

Sketch out model changes for quoted replies.

Sketch out quoted reply input preview.

Send quoted messages protos.

Update models to reflect quoted messages.

Rework interaction initializers.

Rework interaction initializers.

Add debug UI methods for generating quoted reply variations.

Add debug UI methods for generating quoted reply variations.
This commit is contained in:
Matthew Chen 2018-02-07 09:44:09 -08:00 committed by Matthew Chen
parent 308fa59973
commit 8e4f2ca0ed
62 changed files with 2278 additions and 858 deletions

View file

@ -111,7 +111,6 @@
346129C71FD2072E00532771 /* NSString+OWS.h in Headers */ = {isa = PBXBuildFile; fileRef = 346129C01FD2072C00532771 /* NSString+OWS.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346129C71FD2072E00532771 /* NSString+OWS.h in Headers */ = {isa = PBXBuildFile; fileRef = 346129C01FD2072C00532771 /* NSString+OWS.h */; settings = {ATTRIBUTES = (Public, ); }; };
346129C81FD2072E00532771 /* NSAttributedString+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 346129C11FD2072D00532771 /* NSAttributedString+OWS.m */; }; 346129C81FD2072E00532771 /* NSAttributedString+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 346129C11FD2072D00532771 /* NSAttributedString+OWS.m */; };
346129C91FD2072E00532771 /* NSString+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 346129C21FD2072D00532771 /* NSString+OWS.m */; }; 346129C91FD2072E00532771 /* NSString+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 346129C21FD2072D00532771 /* NSString+OWS.m */; };
346129CA1FD2072E00532771 /* UIImage+OWS.h in Headers */ = {isa = PBXBuildFile; fileRef = 346129C31FD2072D00532771 /* UIImage+OWS.h */; settings = {ATTRIBUTES = (Public, ); }; };
346129CB1FD2072E00532771 /* Promise+retainUntilComplete.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346129C41FD2072D00532771 /* Promise+retainUntilComplete.swift */; }; 346129CB1FD2072E00532771 /* Promise+retainUntilComplete.swift in Sources */ = {isa = PBXBuildFile; fileRef = 346129C41FD2072D00532771 /* Promise+retainUntilComplete.swift */; };
346129CC1FD2072E00532771 /* NSAttributedString+OWS.h in Headers */ = {isa = PBXBuildFile; fileRef = 346129C51FD2072D00532771 /* NSAttributedString+OWS.h */; settings = {ATTRIBUTES = (Public, ); }; }; 346129CC1FD2072E00532771 /* NSAttributedString+OWS.h in Headers */ = {isa = PBXBuildFile; fileRef = 346129C51FD2072D00532771 /* NSAttributedString+OWS.h */; settings = {ATTRIBUTES = (Public, ); }; };
346129CD1FD2072E00532771 /* UIImage+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 346129C61FD2072D00532771 /* UIImage+OWS.m */; }; 346129CD1FD2072E00532771 /* UIImage+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 346129C61FD2072D00532771 /* UIImage+OWS.m */; };
@ -684,10 +683,8 @@
346129C01FD2072C00532771 /* NSString+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+OWS.h"; sourceTree = "<group>"; }; 346129C01FD2072C00532771 /* NSString+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSString+OWS.h"; sourceTree = "<group>"; };
346129C11FD2072D00532771 /* NSAttributedString+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributedString+OWS.m"; sourceTree = "<group>"; }; 346129C11FD2072D00532771 /* NSAttributedString+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSAttributedString+OWS.m"; sourceTree = "<group>"; };
346129C21FD2072D00532771 /* NSString+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+OWS.m"; sourceTree = "<group>"; }; 346129C21FD2072D00532771 /* NSString+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSString+OWS.m"; sourceTree = "<group>"; };
346129C31FD2072D00532771 /* UIImage+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "UIImage+OWS.h"; sourceTree = "<group>"; };
346129C41FD2072D00532771 /* Promise+retainUntilComplete.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Promise+retainUntilComplete.swift"; sourceTree = "<group>"; }; 346129C41FD2072D00532771 /* Promise+retainUntilComplete.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "Promise+retainUntilComplete.swift"; sourceTree = "<group>"; };
346129C51FD2072D00532771 /* NSAttributedString+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributedString+OWS.h"; sourceTree = "<group>"; }; 346129C51FD2072D00532771 /* NSAttributedString+OWS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSAttributedString+OWS.h"; sourceTree = "<group>"; };
346129C61FD2072D00532771 /* UIImage+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIImage+OWS.m"; sourceTree = "<group>"; };
346129CF1FD207F200532771 /* OWSAlerts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSAlerts.swift; sourceTree = "<group>"; }; 346129CF1FD207F200532771 /* OWSAlerts.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = OWSAlerts.swift; sourceTree = "<group>"; };
346129D11FD2085A00532771 /* CommonStrings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommonStrings.swift; sourceTree = "<group>"; }; 346129D11FD2085A00532771 /* CommonStrings.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = CommonStrings.swift; sourceTree = "<group>"; };
346129D31FD20ADB00532771 /* UIViewController+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+OWS.m"; sourceTree = "<group>"; }; 346129D31FD20ADB00532771 /* UIViewController+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIViewController+OWS.m"; sourceTree = "<group>"; };
@ -1407,8 +1404,6 @@
34480B5E1FD0A98800BC14EF /* UIColor+OWS.m */, 34480B5E1FD0A98800BC14EF /* UIColor+OWS.m */,
34480B661FD0AA9400BC14EF /* UIFont+OWS.h */, 34480B661FD0AA9400BC14EF /* UIFont+OWS.h */,
34480B651FD0AA9400BC14EF /* UIFont+OWS.m */, 34480B651FD0AA9400BC14EF /* UIFont+OWS.m */,
346129C31FD2072D00532771 /* UIImage+OWS.h */,
346129C61FD2072D00532771 /* UIImage+OWS.m */,
34480B5F1FD0A98800BC14EF /* UIView+OWS.h */, 34480B5F1FD0A98800BC14EF /* UIView+OWS.h */,
34480B601FD0A98800BC14EF /* UIView+OWS.m */, 34480B601FD0A98800BC14EF /* UIView+OWS.m */,
346129D41FD20ADC00532771 /* UIViewController+OWS.h */, 346129D41FD20ADC00532771 /* UIViewController+OWS.h */,
@ -3072,7 +3067,6 @@
347850591FD9972E007B8332 /* SwiftSingletons.swift in Sources */, 347850591FD9972E007B8332 /* SwiftSingletons.swift in Sources */,
344F248720069ECB00CFB4F4 /* ModalActivityIndicatorViewController.swift in Sources */, 344F248720069ECB00CFB4F4 /* ModalActivityIndicatorViewController.swift in Sources */,
346129961FD1E30000532771 /* OWSDatabaseMigration.m in Sources */, 346129961FD1E30000532771 /* OWSDatabaseMigration.m in Sources */,
346129CD1FD2072E00532771 /* UIImage+OWS.m in Sources */,
344D6CEC20069E070042AF96 /* NewNonContactConversationViewController.m in Sources */, 344D6CEC20069E070042AF96 /* NewNonContactConversationViewController.m in Sources */,
346129FB1FD5F31400532771 /* OWS101ExistingUsersBlockOnIdentityChange.m in Sources */, 346129FB1FD5F31400532771 /* OWS101ExistingUsersBlockOnIdentityChange.m in Sources */,
344F248D2007CCD600CFB4F4 /* DisplayableText.swift in Sources */, 344F248D2007CCD600CFB4F4 /* DisplayableText.swift in Sources */,

View file

@ -0,0 +1,23 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "quoted-message-cancel@1x.png",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "quoted-message-cancel@2x.png",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "quoted-message-cancel@3x.png",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.7 KiB

View file

@ -62,7 +62,6 @@
#import <SignalMessaging/ThreadUtil.h> #import <SignalMessaging/ThreadUtil.h>
#import <SignalMessaging/UIColor+OWS.h> #import <SignalMessaging/UIColor+OWS.h>
#import <SignalMessaging/UIFont+OWS.h> #import <SignalMessaging/UIFont+OWS.h>
#import <SignalMessaging/UIImage+OWS.h>
#import <SignalMessaging/UIUtil.h> #import <SignalMessaging/UIUtil.h>
#import <SignalMessaging/UIView+OWS.h> #import <SignalMessaging/UIView+OWS.h>
#import <SignalMessaging/UIViewController+OWS.h> #import <SignalMessaging/UIViewController+OWS.h>
@ -126,6 +125,7 @@
#import <SignalServiceKit/TSSocketManager.h> #import <SignalServiceKit/TSSocketManager.h>
#import <SignalServiceKit/TSThread.h> #import <SignalServiceKit/TSThread.h>
#import <SignalServiceKit/Threading.h> #import <SignalServiceKit/Threading.h>
#import <SignalServiceKit/UIImage+OWS.h>
#import <WebRTC/RTCAudioSession.h> #import <WebRTC/RTCAudioSession.h>
#import <WebRTC/RTCCameraPreviewView.h> #import <WebRTC/RTCCameraPreviewView.h>
#import <YYImage/YYImage.h> #import <YYImage/YYImage.h>

View file

@ -5,6 +5,7 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class SignalAttachment; @class SignalAttachment;
@class TSQuotedMessage;
@protocol ConversationInputToolbarDelegate <NSObject> @protocol ConversationInputToolbarDelegate <NSObject>
@ -57,6 +58,9 @@ NS_ASSUME_NONNULL_BEGIN
- (void)cancelVoiceMemoIfNecessary; - (void)cancelVoiceMemoIfNecessary;
- (void)setQuotedMessage:(TSQuotedMessage *)quotedMessage;
- (void)clearQuotedMessage;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View file

@ -4,6 +4,8 @@
#import "ConversationInputToolbar.h" #import "ConversationInputToolbar.h"
#import "ConversationInputTextView.h" #import "ConversationInputTextView.h"
#import "Environment.h"
#import "OWSContactsManager.h"
#import "OWSMath.h" #import "OWSMath.h"
#import "Signal-Swift.h" #import "Signal-Swift.h"
#import "UIColor+OWS.h" #import "UIColor+OWS.h"
@ -12,11 +14,104 @@
#import "ViewControllerUtils.h" #import "ViewControllerUtils.h"
#import <SignalMessaging/OWSFormat.h> #import <SignalMessaging/OWSFormat.h>
#import <SignalServiceKit/NSTimer+OWS.h> #import <SignalServiceKit/NSTimer+OWS.h>
#import <SignalServiceKit/TSQuotedMessage.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
static void *kConversationInputTextViewObservingContext = &kConversationInputTextViewObservingContext; static void *kConversationInputTextViewObservingContext = &kConversationInputTextViewObservingContext;
static const CGFloat ConversationInputToolbarBorderViewHeight = 0.5; static const CGFloat ConversationInputToolbarBorderViewHeight = 0.5;
@interface QuotedMessagePreviewView : UIView
@property (nonatomic, readonly) UILabel *titleLabel;
@property (nonatomic, readonly) UILabel *bodyLabel;
@property (nonatomic, readonly) UIImageView *iconView;
@property (nonatomic, readonly) UIButton *cancelButton;
@property (nonatomic, readonly) UIView *quoteStripe;
@end
@implementation QuotedMessagePreviewView
- (nullable UIImageView *)iconForMessage:(TSQuotedMessage *)message
{
// FIXME TODO
return nil;
}
- (instancetype)initWithQuotedMessage:(TSQuotedMessage *)message
{
self = [super initWithFrame:CGRectZero];
if (!self) {
return self;
}
_titleLabel = [UILabel new];
_titleLabel.text = [[Environment current].contactsManager displayNameForPhoneIdentifier:message.authorId];
_bodyLabel = [UILabel new];
_bodyLabel.text = message.body;
_iconView = [self iconForMessage:message];
if (_iconView) {
[self addSubview:_iconView];
}
_cancelButton = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *buttonImage =
[[UIImage imageNamed:@"quoted-message-cancel"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
[_cancelButton setImage:buttonImage forState:UIControlStateNormal];
_cancelButton.imageView.tintColor = [UIColor ows_blackColor];
_quoteStripe = [UIView new];
BOOL isQuotingSelf = [message.authorId isEqualToString:[TSAccountManager localNumber]];
// FIXME actual colors TBD
_quoteStripe.backgroundColor = isQuotingSelf ? [UIColor orangeColor] : [UIColor blackColor];
UIView *contentContainer = [UIView containerView];
[self addSubview:_titleLabel];
[self addSubview:contentContainer];
[contentContainer addSubview:_bodyLabel];
[self addSubview:_cancelButton];
[self addSubview:_quoteStripe];
// Layout
CGFloat kLeadingMargin = 4;
[_quoteStripe autoPinEdgesToSuperviewEdgesWithInsets:UIEdgeInsetsZero excludingEdge:ALEdgeRight];
[_titleLabel autoPinEdgeToSuperviewEdge:ALEdgeTop];
[_titleLabel autoPinEdge:ALEdgeLeading toEdge:ALEdgeTrailing ofView:_quoteStripe withOffset:kLeadingMargin];
[_titleLabel autoPinEdge:ALEdgeTrailing toEdge:ALEdgeLeading ofView:_cancelButton];
if (_iconView) {
[contentContainer addSubview:_iconView];
[_iconView autoPinEdgeToSuperviewEdge:ALEdgeLeading];
[_iconView autoPinEdge:ALEdgeTrailing toEdge:ALEdgeTrailing ofView:_bodyLabel];
[_iconView autoPinHeightToSuperview];
} else {
[_bodyLabel autoPinEdge:ALEdgeLeading toEdge:ALEdgeTrailing ofView:_quoteStripe withOffset:kLeadingMargin];
}
[_bodyLabel autoPinHeightToSuperview];
[_bodyLabel autoPinEdgeToSuperviewEdge:ALEdgeTrailing];
[contentContainer autoPinEdge:ALEdgeTop toEdge:ALEdgeBottom ofView:_titleLabel];
[contentContainer autoPinEdge:ALEdgeTrailing toEdge:ALEdgeLeading ofView:_cancelButton];
[contentContainer autoPinEdgeToSuperviewEdge:ALEdgeBottom];
[_cancelButton autoPinEdgeToSuperviewEdge:ALEdgeTop];
[_cancelButton autoVCenterInSuperview];
return self;
}
@end
#pragma mark -
@interface ConversationInputToolbar () <UIGestureRecognizerDelegate, ConversationTextViewToolbarDelegate> @interface ConversationInputToolbar () <UIGestureRecognizerDelegate, ConversationTextViewToolbarDelegate>
@property (nonatomic, readonly) UIView *contentView; @property (nonatomic, readonly) UIView *contentView;
@ -34,6 +129,10 @@ static const CGFloat ConversationInputToolbarBorderViewHeight = 0.5;
@property (nonatomic) CGFloat toolbarHeight; @property (nonatomic) CGFloat toolbarHeight;
@property (nonatomic) CGFloat textViewHeight; @property (nonatomic) CGFloat textViewHeight;
#pragma mark -
@property (nonatomic, nullable) QuotedMessagePreviewView *quotedMessageView;
#pragma mark - Voice Memo Recording UI #pragma mark - Voice Memo Recording UI
@property (nonatomic, nullable) UIView *voiceMemoUI; @property (nonatomic, nullable) UIView *voiceMemoUI;
@ -46,6 +145,9 @@ static const CGFloat ConversationInputToolbarBorderViewHeight = 0.5;
@end @end
#pragma mark -
#pragma mark - #pragma mark -
@implementation ConversationInputToolbar @implementation ConversationInputToolbar
@ -226,6 +328,18 @@ static const CGFloat ConversationInputToolbarBorderViewHeight = 0.5;
[self ensureContentConstraints]; [self ensureContentConstraints];
} }
- (void)setQuotedMessage:(TSQuotedMessage *)quotedMessage
{
QuotedMessagePreviewView *quotedMessageView =
[[QuotedMessagePreviewView alloc] initWithQuotedMessage:quotedMessage];
[self ensureContentConstraints];
}
- (void)clearQuotedMessage
{
}
- (void)beginEditingTextMessage - (void)beginEditingTextMessage
{ {
[self.inputTextView becomeFirstResponder]; [self.inputTextView becomeFirstResponder];

View file

@ -3549,9 +3549,15 @@ typedef enum : NSUInteger {
groupThread.groupModel = newGroupModel; groupThread.groupModel = newGroupModel;
[groupThread saveWithTransaction:transaction]; [groupThread saveWithTransaction:transaction];
message = [[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] message = [[TSOutgoingMessage alloc] initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:groupThread inThread:groupThread
groupMetaMessage:TSGroupMessageUpdate]; messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageUpdate
quotedMessage:nil];
[message updateWithCustomMessage:updateGroupInfo transaction:transaction]; [message updateWithCustomMessage:updateGroupInfo transaction:transaction];
}]; }];

File diff suppressed because it is too large Load diff

View file

@ -12,7 +12,6 @@
#import <AxolotlKit/PreKeyBundle.h> #import <AxolotlKit/PreKeyBundle.h>
#import <SignalMessaging/AttachmentSharing.h> #import <SignalMessaging/AttachmentSharing.h>
#import <SignalMessaging/Environment.h> #import <SignalMessaging/Environment.h>
#import <SignalMessaging/UIImage+OWS.h>
#import <SignalServiceKit/OWSDisappearingConfigurationUpdateInfoMessage.h> #import <SignalServiceKit/OWSDisappearingConfigurationUpdateInfoMessage.h>
#import <SignalServiceKit/OWSDisappearingMessagesConfiguration.h> #import <SignalServiceKit/OWSDisappearingMessagesConfiguration.h>
#import <SignalServiceKit/OWSPrimaryStorage+SessionStore.h> #import <SignalServiceKit/OWSPrimaryStorage+SessionStore.h>
@ -21,6 +20,7 @@
#import <SignalServiceKit/TSCall.h> #import <SignalServiceKit/TSCall.h>
#import <SignalServiceKit/TSInvalidIdentityKeyReceivingErrorMessage.h> #import <SignalServiceKit/TSInvalidIdentityKeyReceivingErrorMessage.h>
#import <SignalServiceKit/TSThread.h> #import <SignalServiceKit/TSThread.h>
#import <SignalServiceKit/UIImage+OWS.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View file

@ -683,9 +683,16 @@ typedef NS_ENUM(NSInteger, CellState) { kArchiveState, kInboxState };
preferredStyle:UIAlertControllerStyleAlert]; preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:removingFromGroup animated:YES completion:nil]; [self presentViewController:removingFromGroup animated:YES completion:nil];
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] TSOutgoingMessage *message =
[[TSOutgoingMessage alloc] initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread inThread:thread
groupMetaMessage:TSGroupMessageQuit]; messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageQuit
quotedMessage:nil];
[self.messageSender enqueueMessage:message [self.messageSender enqueueMessage:message
success:^{ success:^{
[self dismissViewControllerAnimated:YES [self dismissViewControllerAnimated:YES

View file

@ -490,9 +490,15 @@ const NSUInteger kNewGroupViewControllerAvatarWidth = 68;
canCancel:NO canCancel:NO
backgroundBlock:^(ModalActivityIndicatorViewController *modalActivityIndicator) { backgroundBlock:^(ModalActivityIndicatorViewController *modalActivityIndicator) {
TSOutgoingMessage *message = TSOutgoingMessage *message =
[[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] [[TSOutgoingMessage alloc] initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread inThread:thread
groupMetaMessage:TSGroupMessageNew]; messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageNew
quotedMessage:nil];
[message updateWithCustomMessage:NSLocalizedString(@"GROUP_CREATED", nil)]; [message updateWithCustomMessage:NSLocalizedString(@"GROUP_CREATED", nil)];

View file

@ -936,9 +936,16 @@ NS_ASSUME_NONNULL_BEGIN
- (void)leaveGroup - (void)leaveGroup
{ {
TSGroupThread *gThread = (TSGroupThread *)self.thread; TSGroupThread *gThread = (TSGroupThread *)self.thread;
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] TSOutgoingMessage *message =
[[TSOutgoingMessage alloc] initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:gThread inThread:gThread
groupMetaMessage:TSGroupMessageQuit]; messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageQuit
quotedMessage:nil];
[self.messageSender enqueueMessage:message [self.messageSender enqueueMessage:message
success:^{ success:^{
DDLogInfo(@"%@ Successfully left group.", self.logTag); DDLogInfo(@"%@ Successfully left group.", self.logTag);

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import <SignalServiceKit/TSInteraction.h> #import <SignalServiceKit/TSInteraction.h>
@ -13,9 +13,11 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) BOOL hasAddToProfileWhitelistOffer; @property (nonatomic, readonly) BOOL hasAddToProfileWhitelistOffer;
@property (nonatomic, readonly) NSString *recipientId; @property (nonatomic, readonly) NSString *recipientId;
- (instancetype)initInteractionWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread NS_UNAVAILABLE;
- (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; - (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithTimestamp:(uint64_t)timestamp - (instancetype)initContactOffersWithTimestamp:(uint64_t)timestamp
thread:(TSThread *)thread thread:(TSThread *)thread
hasBlockOffer:(BOOL)hasBlockOffer hasBlockOffer:(BOOL)hasBlockOffer
hasAddToContactsOffer:(BOOL)hasAddToContactsOffer hasAddToContactsOffer:(BOOL)hasAddToContactsOffer

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSContactOffersInteraction.h" #import "OWSContactOffersInteraction.h"
@ -13,14 +13,14 @@ NS_ASSUME_NONNULL_BEGIN
return [super initWithCoder:coder]; return [super initWithCoder:coder];
} }
- (instancetype)initWithTimestamp:(uint64_t)timestamp - (instancetype)initContactOffersWithTimestamp:(uint64_t)timestamp
thread:(TSThread *)thread thread:(TSThread *)thread
hasBlockOffer:(BOOL)hasBlockOffer hasBlockOffer:(BOOL)hasBlockOffer
hasAddToContactsOffer:(BOOL)hasAddToContactsOffer hasAddToContactsOffer:(BOOL)hasAddToContactsOffer
hasAddToProfileWhitelistOffer:(BOOL)hasAddToProfileWhitelistOffer hasAddToProfileWhitelistOffer:(BOOL)hasAddToProfileWhitelistOffer
recipientId:(NSString *)recipientId recipientId:(NSString *)recipientId
{ {
self = [super initWithTimestamp:timestamp inThread:thread]; self = [super initInteractionWithTimestamp:timestamp inThread:thread];
if (!self) { if (!self) {
return self; return self;

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import <SignalServiceKit/TSInteraction.h> #import <SignalServiceKit/TSInteraction.h>
@ -12,12 +12,15 @@ NS_ASSUME_NONNULL_BEGIN
@property (atomic, readonly) NSUInteger missingUnseenSafetyNumberChangeCount; @property (atomic, readonly) NSUInteger missingUnseenSafetyNumberChangeCount;
- (instancetype)initInteractionWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread NS_UNAVAILABLE;
- (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; - (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithTimestamp:(uint64_t)timestamp - (instancetype)initUnreadIndicatorWithTimestamp:(uint64_t)timestamp
thread:(TSThread *)thread thread:(TSThread *)thread
hasMoreUnseenMessages:(BOOL)hasMoreUnseenMessages hasMoreUnseenMessages:(BOOL)hasMoreUnseenMessages
missingUnseenSafetyNumberChangeCount:(NSUInteger)missingUnseenSafetyNumberChangeCount NS_DESIGNATED_INITIALIZER; missingUnseenSafetyNumberChangeCount:(NSUInteger)missingUnseenSafetyNumberChangeCount
NS_DESIGNATED_INITIALIZER;
@end @end

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "TSUnreadIndicatorInteraction.h" #import "TSUnreadIndicatorInteraction.h"
@ -21,12 +21,12 @@ NS_ASSUME_NONNULL_BEGIN
return [super initWithCoder:coder]; return [super initWithCoder:coder];
} }
- (instancetype)initWithTimestamp:(uint64_t)timestamp - (instancetype)initUnreadIndicatorWithTimestamp:(uint64_t)timestamp
thread:(TSThread *)thread thread:(TSThread *)thread
hasMoreUnseenMessages:(BOOL)hasMoreUnseenMessages hasMoreUnseenMessages:(BOOL)hasMoreUnseenMessages
missingUnseenSafetyNumberChangeCount:(NSUInteger)missingUnseenSafetyNumberChangeCount missingUnseenSafetyNumberChangeCount:(NSUInteger)missingUnseenSafetyNumberChangeCount
{ {
self = [super initWithTimestamp:timestamp inThread:thread]; self = [super initInteractionWithTimestamp:timestamp inThread:thread];
if (!self) { if (!self) {
return self; return self;

View file

@ -40,9 +40,9 @@ FOUNDATION_EXPORT const unsigned char SignalMessagingVersionString[];
#import <SignalMessaging/ThreadUtil.h> #import <SignalMessaging/ThreadUtil.h>
#import <SignalMessaging/UIColor+OWS.h> #import <SignalMessaging/UIColor+OWS.h>
#import <SignalMessaging/UIFont+OWS.h> #import <SignalMessaging/UIFont+OWS.h>
#import <SignalMessaging/UIImage+OWS.h>
#import <SignalMessaging/UIUtil.h> #import <SignalMessaging/UIUtil.h>
#import <SignalMessaging/UIView+OWS.h> #import <SignalMessaging/UIView+OWS.h>
#import <SignalMessaging/UIViewController+OWS.h> #import <SignalMessaging/UIViewController+OWS.h>
#import <SignalMessaging/VersionMigrations.h> #import <SignalMessaging/VersionMigrations.h>
#import <SignalMessaging/ViewControllerUtils.h> #import <SignalMessaging/ViewControllerUtils.h>
#import <SignalServiceKit/UIImage+OWS.h>

View file

@ -6,7 +6,6 @@
#import "Environment.h" #import "Environment.h"
#import "NSString+OWS.h" #import "NSString+OWS.h"
#import "OWSUserProfile.h" #import "OWSUserProfile.h"
#import "UIImage+OWS.h"
#import <SignalMessaging/SignalMessaging-Swift.h> #import <SignalMessaging/SignalMessaging-Swift.h>
#import <SignalServiceKit/AppContext.h> #import <SignalServiceKit/AppContext.h>
#import <SignalServiceKit/Cryptography.h> #import <SignalServiceKit/Cryptography.h>
@ -28,6 +27,7 @@
#import <SignalServiceKit/TSThread.h> #import <SignalServiceKit/TSThread.h>
#import <SignalServiceKit/TSYapDatabaseObject.h> #import <SignalServiceKit/TSYapDatabaseObject.h>
#import <SignalServiceKit/TextSecureKitEnv.h> #import <SignalServiceKit/TextSecureKitEnv.h>
#import <SignalServiceKit/UIImage+OWS.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN

View file

@ -82,12 +82,15 @@ NS_ASSUME_NONNULL_BEGIN
OWSDisappearingMessagesConfiguration *configuration = OWSDisappearingMessagesConfiguration *configuration =
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId]; [OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId];
TSOutgoingMessage *message = TSOutgoingMessage *message = [[TSOutgoingMessage alloc]
[[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread inThread:thread
messageBody:text messageBody:text
attachmentIds:[NSMutableArray new] attachmentIds:[NSMutableArray new]
expiresInSeconds:(configuration.isEnabled ? configuration.durationSeconds : 0)]; expiresInSeconds:(configuration.isEnabled ? configuration.durationSeconds : 0)expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageNone
quotedMessage:nil];
[messageSender enqueueMessage:message success:successHandler failure:failureHandler]; [messageSender enqueueMessage:message success:successHandler failure:failureHandler];
@ -121,12 +124,15 @@ NS_ASSUME_NONNULL_BEGIN
OWSDisappearingMessagesConfiguration *configuration = OWSDisappearingMessagesConfiguration *configuration =
[OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId]; [OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:thread.uniqueId];
TSOutgoingMessage *message = TSOutgoingMessage *message = [[TSOutgoingMessage alloc]
[[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread inThread:thread
messageBody:attachment.captionText messageBody:attachment.captionText
attachmentIds:[NSMutableArray new]
expiresInSeconds:(configuration.isEnabled ? configuration.durationSeconds : 0)expireStartedAt:0
isVoiceMessage:[attachment isVoiceMessage] isVoiceMessage:[attachment isVoiceMessage]
expiresInSeconds:(configuration.isEnabled ? configuration.durationSeconds : 0)]; groupMetaMessage:TSGroupMessageNone
quotedMessage:nil];
[messageSender enqueueAttachment:attachment.dataSource [messageSender enqueueAttachment:attachment.dataSource
contentType:attachment.mimeType contentType:attachment.mimeType
@ -499,7 +505,7 @@ NS_ASSUME_NONNULL_BEGIN
NSString *recipientId = ((TSContactThread *)thread).contactIdentifier; NSString *recipientId = ((TSContactThread *)thread).contactIdentifier;
TSInteraction *offersMessage = TSInteraction *offersMessage =
[[OWSContactOffersInteraction alloc] initWithTimestamp:contactOffersTimestamp [[OWSContactOffersInteraction alloc] initContactOffersWithTimestamp:contactOffersTimestamp
thread:thread thread:thread
hasBlockOffer:shouldHaveBlockOffer hasBlockOffer:shouldHaveBlockOffer
hasAddToContactsOffer:shouldHaveAddToContactsOffer hasAddToContactsOffer:shouldHaveAddToContactsOffer
@ -540,8 +546,8 @@ NS_ASSUME_NONNULL_BEGIN
[existingUnreadIndicator removeWithTransaction:transaction]; [existingUnreadIndicator removeWithTransaction:transaction];
} }
TSUnreadIndicatorInteraction *indicator = TSUnreadIndicatorInteraction *indicator = [[TSUnreadIndicatorInteraction alloc]
[[TSUnreadIndicatorInteraction alloc] initWithTimestamp:indicatorTimestamp initUnreadIndicatorWithTimestamp:indicatorTimestamp
thread:thread thread:thread
hasMoreUnseenMessages:result.hasMoreUnseenMessages hasMoreUnseenMessages:result.hasMoreUnseenMessages
missingUnseenSafetyNumberChangeCount:missingUnseenSafetyNumberChangeCount]; missingUnseenSafetyNumberChangeCount:missingUnseenSafetyNumberChangeCount];

View file

@ -1,11 +1,11 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "UIColor+OWS.h" #import "UIColor+OWS.h"
#import "UIFont+OWS.h" #import "UIFont+OWS.h"
#import "UIImage+OWS.h"
#import <SignalServiceKit/MIMETypeUtil.h> #import <SignalServiceKit/MIMETypeUtil.h>
#import <SignalServiceKit/UIImage+OWS.h>
typedef void (^completionBlock)(void); typedef void (^completionBlock)(void);

View file

@ -87,6 +87,14 @@ message DataMessage {
PROFILE_KEY_UPDATE = 4; PROFILE_KEY_UPDATE = 4;
} }
message Quote
{
optional uint64 id = 1;
optional string author = 2;
optional string text = 3;
optional AttachmentPointer attachment = 4;
}
optional string body = 1; optional string body = 1;
repeated AttachmentPointer attachments = 2; repeated AttachmentPointer attachments = 2;
optional GroupContext group = 3; optional GroupContext group = 3;
@ -94,6 +102,7 @@ message DataMessage {
optional uint32 expireTimer = 5; optional uint32 expireTimer = 5;
optional bytes profileKey = 6; optional bytes profileKey = 6;
optional uint64 timestamp = 7; optional uint64 timestamp = 7;
optional Quote quote = 8;
} }
message NullMessage { message NullMessage {

View file

@ -15,11 +15,21 @@ NS_ASSUME_NONNULL_BEGIN
@end @end
#pragma mark -
@implementation OWSReadReceiptsForSenderMessage @implementation OWSReadReceiptsForSenderMessage
- (instancetype)initWithThread:(nullable TSThread *)thread messageTimestamps:(NSArray<NSNumber *> *)messageTimestamps - (instancetype)initWithThread:(nullable TSThread *)thread messageTimestamps:(NSArray<NSNumber *> *)messageTimestamps
{ {
self = [super initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:thread]; self = [super initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageNone
quotedMessage:nil];
if (!self) { if (!self) {
return self; return self;
} }

View file

@ -88,12 +88,15 @@ NS_ASSUME_NONNULL_BEGIN
// TODO group updates. Currently desktop doesn't support group updates, so not a problem yet. // TODO group updates. Currently desktop doesn't support group updates, so not a problem yet.
TSOutgoingMessage *outgoingMessage = TSOutgoingMessage *outgoingMessage =
[[TSOutgoingMessage alloc] initWithTimestamp:transcript.timestamp [[TSOutgoingMessage alloc] initOutgoingMessageWithTimestamp:transcript.timestamp
inThread:thread inThread:thread
messageBody:transcript.body messageBody:transcript.body
attachmentIds:[attachmentsProcessor.attachmentIds mutableCopy] attachmentIds:[attachmentsProcessor.attachmentIds mutableCopy]
expiresInSeconds:transcript.expirationDuration expiresInSeconds:transcript.expirationDuration
expireStartedAt:transcript.expirationStartedAt]; expireStartedAt:transcript.expirationStartedAt
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageNone
quotedMessage:nil];
if (transcript.isExpirationTimerUpdate) { if (transcript.isExpirationTimerUpdate) {
[OWSDisappearingMessagesJob becomeConsistentWithConfigurationForMessage:outgoingMessage [OWSDisappearingMessagesJob becomeConsistentWithConfigurationForMessage:outgoingMessage

View file

@ -180,6 +180,8 @@ NSUInteger const TSAttachmentSchemaVersion = 4;
} }
} else if ([MIMETypeUtil isAnimated:self.contentType]) { } else if ([MIMETypeUtil isAnimated:self.contentType]) {
return [NSString stringWithFormat:@"🎡 %@", attachmentString]; return [NSString stringWithFormat:@"🎡 %@", attachmentString];
} else {
return [NSString stringWithFormat:@"📎 %@", attachmentString];
} }
return attachmentString; return attachmentString;

View file

@ -14,7 +14,16 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)init - (instancetype)init
{ {
self = [super initWithTimestamp:[NSDate ows_millisecondTimeStamp]]; self = [super initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:nil
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageNone
quotedMessage:nil];
if (!self) { if (!self) {
return self; return self;
} }

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSSyncContactsMessage.h" #import "OWSSyncContactsMessage.h"
@ -30,7 +30,15 @@ NS_ASSUME_NONNULL_BEGIN
identityManager:(OWSIdentityManager *)identityManager identityManager:(OWSIdentityManager *)identityManager
profileManager:(id<ProfileManagerProtocol>)profileManager profileManager:(id<ProfileManagerProtocol>)profileManager
{ {
self = [super initWithTimestamp:[NSDate ows_millisecondTimeStamp]]; self = [super initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:nil
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageNone
quotedMessage:nil];
if (!self) { if (!self) {
return self; return self;
} }

View file

@ -16,7 +16,15 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)init - (instancetype)init
{ {
return [super initWithTimestamp:[NSDate ows_millisecondTimeStamp]]; return [super initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:nil
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageNone
quotedMessage:nil];
} }
- (OWSSignalServiceProtosSyncMessageBuilder *)syncMessageBuilder - (OWSSignalServiceProtosSyncMessageBuilder *)syncMessageBuilder

View file

@ -20,7 +20,15 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithThread:(nullable TSThread *)thread groupId:(NSData *)groupId - (instancetype)initWithThread:(nullable TSThread *)thread groupId:(NSData *)groupId
{ {
self = [super initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:thread]; self = [super initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageNone
quotedMessage:nil];
if (!self) { if (!self) {
return self; return self;
} }

View file

@ -15,6 +15,8 @@ NS_ASSUME_NONNULL_BEGIN
@end @end
#pragma mark -
@implementation OWSDisappearingMessagesConfigurationMessage @implementation OWSDisappearingMessagesConfigurationMessage
- (BOOL)shouldBeSaved - (BOOL)shouldBeSaved
@ -24,7 +26,15 @@ NS_ASSUME_NONNULL_BEGIN
- (instancetype)initWithConfiguration:(OWSDisappearingMessagesConfiguration *)configuration thread:(TSThread *)thread - (instancetype)initWithConfiguration:(OWSDisappearingMessagesConfiguration *)configuration thread:(TSThread *)thread
{ {
self = [super initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:thread]; self = [super initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageNone
quotedMessage:nil];
if (!self) { if (!self) {
return self; return self;
} }

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSDynamicOutgoingMessage.h" #import "OWSDynamicOutgoingMessage.h"
@ -27,7 +27,15 @@ NS_ASSUME_NONNULL_BEGIN
timestamp:(uint64_t)timestamp timestamp:(uint64_t)timestamp
thread:(nullable TSThread *)thread thread:(nullable TSThread *)thread
{ {
self = [super initWithTimestamp:timestamp inThread:thread]; self = [super initOutgoingMessageWithTimestamp:timestamp
inThread:thread
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageNone
quotedMessage:nil];
if (self) { if (self) {
_block = block; _block = block;

View file

@ -1,5 +1,6 @@
// Created by Michael Kirk on 11/3/16. //
// Copyright © 2016 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "TSOutgoingMessage.h" #import "TSOutgoingMessage.h"
@ -8,6 +9,8 @@ NS_ASSUME_NONNULL_BEGIN
NS_SWIFT_NAME(EndSessionMessage) NS_SWIFT_NAME(EndSessionMessage)
@interface OWSEndSessionMessage : TSOutgoingMessage @interface OWSEndSessionMessage : TSOutgoingMessage
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(nullable TSThread *)thread NS_DESIGNATED_INITIALIZER;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View file

@ -9,6 +9,19 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSEndSessionMessage @implementation OWSEndSessionMessage
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(nullable TSThread *)thread
{
return [super initOutgoingMessageWithTimestamp:timestamp
inThread:thread
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageNone
quotedMessage:nil];
}
- (BOOL)shouldBeSaved - (BOOL)shouldBeSaved
{ {
return NO; return NO;

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSReadTracking.h" #import "OWSReadTracking.h"
@ -8,8 +8,6 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@interface TSErrorMessage : TSMessage <OWSReadTracking>
typedef NS_ENUM(int32_t, TSErrorMessageType) { typedef NS_ENUM(int32_t, TSErrorMessageType) {
TSErrorMessageNoSession, TSErrorMessageNoSession,
TSErrorMessageWrongTrustedIdentityKey, // DEPRECATED: We no longer create TSErrorMessageWrongTrustedIdentityKey, but TSErrorMessageWrongTrustedIdentityKey, // DEPRECATED: We no longer create TSErrorMessageWrongTrustedIdentityKey, but
@ -24,6 +22,16 @@ typedef NS_ENUM(int32_t, TSErrorMessageType) {
TSErrorMessageGroupCreationFailed, TSErrorMessageGroupCreationFailed,
}; };
@interface TSErrorMessage : TSMessage <OWSReadTracking>
- (instancetype)initMessageWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
attachmentIds:(NSArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds
expireStartedAt:(uint64_t)expireStartedAt
quotedMessage:(nullable TSQuotedMessage *)quotedMessage NS_UNAVAILABLE;
- (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; - (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithTimestamp:(uint64_t)timestamp - (instancetype)initWithTimestamp:(uint64_t)timestamp

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "TSErrorMessage.h" #import "TSErrorMessage.h"
@ -59,12 +59,13 @@ NSUInteger TSErrorMessageSchemaVersion = 1;
failedMessageType:(TSErrorMessageType)errorMessageType failedMessageType:(TSErrorMessageType)errorMessageType
recipientId:(nullable NSString *)recipientId recipientId:(nullable NSString *)recipientId
{ {
self = [super initWithTimestamp:timestamp self = [super initMessageWithTimestamp:timestamp
inThread:thread inThread:thread
messageBody:nil messageBody:nil
attachmentIds:@[] attachmentIds:@[]
expiresInSeconds:0 expiresInSeconds:0
expireStartedAt:0]; expireStartedAt:0
quotedMessage:nil];
if (!self) { if (!self) {
return self; return self;

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSReadTracking.h" #import "OWSReadTracking.h"
@ -12,27 +12,13 @@ NS_ASSUME_NONNULL_BEGIN
@interface TSIncomingMessage : TSMessage <OWSReadTracking> @interface TSIncomingMessage : TSMessage <OWSReadTracking>
/** - (instancetype)initMessageWithTimestamp:(uint64_t)timestamp
* Inits an incoming group message without attachments inThread:(nullable TSThread *)thread
* messageBody:(nullable NSString *)body
* @param timestamp attachmentIds:(NSArray<NSString *> *)attachmentIds
* When the message was created in milliseconds since epoch expiresInSeconds:(uint32_t)expiresInSeconds
* @param thread expireStartedAt:(uint64_t)expireStartedAt
* Thread to which the message belongs quotedMessage:(nullable TSQuotedMessage *)quotedMessage NS_UNAVAILABLE;
* @param authorId
* Signal ID (i.e. e164) of the user who sent the message
* @param sourceDeviceId
* Numeric ID of the device used to send the message. Used to detect duplicate messages.
* @param body
* Body of the message
*
* @return initiated incoming group message
*/
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(TSThread *)thread
authorId:(NSString *)authorId
sourceDeviceId:(uint32_t)sourceDeviceId
messageBody:(nullable NSString *)body;
/** /**
* Inits an incoming group message that expires. * Inits an incoming group message that expires.
@ -51,45 +37,22 @@ NS_ASSUME_NONNULL_BEGIN
* The uniqueIds for the message's attachments, possibly an empty list. * The uniqueIds for the message's attachments, possibly an empty list.
* @param expiresInSeconds * @param expiresInSeconds
* Seconds from when the message is read until it is deleted. * Seconds from when the message is read until it is deleted.
* @param quotedMessage
* If this message is a quoted reply to another message, contains data about that message.
* *
* @return initiated incoming group message * @return initiated incoming group message
*/ */
- (instancetype)initWithTimestamp:(uint64_t)timestamp - (instancetype)initIncomingMessageWithTimestamp:(uint64_t)timestamp
inThread:(TSThread *)thread inThread:(TSThread *)thread
authorId:(NSString *)authorId authorId:(NSString *)authorId
sourceDeviceId:(uint32_t)sourceDeviceId sourceDeviceId:(uint32_t)sourceDeviceId
messageBody:(nullable NSString *)body messageBody:(nullable NSString *)body
attachmentIds:(NSArray<NSString *> *)attachmentIds attachmentIds:(NSArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds NS_DESIGNATED_INITIALIZER; expiresInSeconds:(uint32_t)expiresInSeconds
quotedMessage:(nullable TSQuotedMessage *)quotedMessage NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; - (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
/**
* For sake of a smaller API, and simplifying assumptions elsewhere, you must specify an author id for *all* incoming
* messages, even though we technically could infer the author id for a contact thread.
*/
- (instancetype)initWithTimestamp:(uint64_t)timestamp NS_UNAVAILABLE;
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(nullable TSThread *)thread NS_UNAVAILABLE;
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body NS_UNAVAILABLE;
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
attachmentIds:(NSArray<NSString *> *)attachmentIds NS_UNAVAILABLE;
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
attachmentIds:(NSArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds NS_UNAVAILABLE;
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
attachmentIds:(NSArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds
expireStartedAt:(uint64_t)expireStartedAt NS_UNAVAILABLE;
/* /*
* Find a message matching the senderId and timestamp, if any. * Find a message matching the senderId and timestamp, if any.
* *

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "TSIncomingMessage.h" #import "TSIncomingMessage.h"
@ -35,35 +35,22 @@ NS_ASSUME_NONNULL_BEGIN
return self; return self;
} }
- (instancetype)initWithTimestamp:(uint64_t)timestamp - (instancetype)initIncomingMessageWithTimestamp:(uint64_t)timestamp
inThread:(TSThread *)thread
authorId:(NSString *)authorId
sourceDeviceId:(uint32_t)sourceDeviceId
messageBody:(nullable NSString *)body
{
return [self initWithTimestamp:timestamp
inThread:thread
authorId:authorId
sourceDeviceId:sourceDeviceId
messageBody:body
attachmentIds:@[]
expiresInSeconds:0];
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(TSThread *)thread inThread:(TSThread *)thread
authorId:(NSString *)authorId authorId:(NSString *)authorId
sourceDeviceId:(uint32_t)sourceDeviceId sourceDeviceId:(uint32_t)sourceDeviceId
messageBody:(nullable NSString *)body messageBody:(nullable NSString *)body
attachmentIds:(NSArray<NSString *> *)attachmentIds attachmentIds:(NSArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds expiresInSeconds:(uint32_t)expiresInSeconds
quotedMessage:(nullable TSQuotedMessage *)quotedMessage
{ {
self = [super initWithTimestamp:timestamp self = [super initMessageWithTimestamp:timestamp
inThread:thread inThread:thread
messageBody:body messageBody:body
attachmentIds:attachmentIds attachmentIds:attachmentIds
expiresInSeconds:expiresInSeconds expiresInSeconds:expiresInSeconds
expireStartedAt:0]; expireStartedAt:0
quotedMessage:quotedMessage];
if (!self) { if (!self) {
return self; return self;

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSReadTracking.h" #import "OWSReadTracking.h"
@ -28,6 +28,14 @@ typedef NS_ENUM(NSInteger, TSInfoMessageType) {
@property (atomic, readonly) TSInfoMessageType messageType; @property (atomic, readonly) TSInfoMessageType messageType;
@property (atomic, readonly) NSString *customMessage; @property (atomic, readonly) NSString *customMessage;
- (instancetype)initMessageWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
attachmentIds:(NSArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds
expireStartedAt:(uint64_t)expireStartedAt
quotedMessage:(nullable TSQuotedMessage *)quotedMessage NS_UNAVAILABLE;
- (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; - (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithTimestamp:(uint64_t)timestamp - (instancetype)initWithTimestamp:(uint64_t)timestamp

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "TSInfoMessage.h" #import "TSInfoMessage.h"
@ -46,12 +46,13 @@ NSUInteger TSInfoMessageSchemaVersion = 1;
inThread:(TSThread *)thread inThread:(TSThread *)thread
messageType:(TSInfoMessageType)infoMessage messageType:(TSInfoMessageType)infoMessage
{ {
self = [super initWithTimestamp:timestamp self = [super initMessageWithTimestamp:timestamp
inThread:thread inThread:thread
messageBody:nil messageBody:nil
attachmentIds:@[] attachmentIds:@[]
expiresInSeconds:0 expiresInSeconds:0
expireStartedAt:0]; expireStartedAt:0
quotedMessage:nil];
if (!self) { if (!self) {
return self; return self;

View file

@ -21,7 +21,7 @@ typedef NS_ENUM(NSInteger, OWSInteractionType) {
@interface TSInteraction : TSYapDatabaseObject @interface TSInteraction : TSYapDatabaseObject
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread; - (instancetype)initInteractionWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread;
@property (nonatomic, readonly) NSString *uniqueThreadId; @property (nonatomic, readonly) NSString *uniqueThreadId;
@property (nonatomic, readonly) TSThread *thread; @property (nonatomic, readonly) TSThread *thread;

View file

@ -54,7 +54,7 @@ NS_ASSUME_NONNULL_BEGIN
return @"TSInteraction"; return @"TSInteraction";
} }
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread - (instancetype)initInteractionWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread
{ {
OWSAssert(timestamp > 0); OWSAssert(timestamp > 0);

View file

@ -11,6 +11,7 @@ NS_ASSUME_NONNULL_BEGIN
*/ */
@class TSAttachment; @class TSAttachment;
@class TSQuotedMessage;
@interface TSMessage : TSInteraction @interface TSMessage : TSInteraction
@ -20,32 +21,17 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, readonly) uint64_t expireStartedAt; @property (nonatomic, readonly) uint64_t expireStartedAt;
@property (nonatomic, readonly) uint64_t expiresAt; @property (nonatomic, readonly) uint64_t expiresAt;
@property (nonatomic, readonly) BOOL isExpiringMessage; @property (nonatomic, readonly) BOOL isExpiringMessage;
@property (nonatomic, readonly, nullable) TSQuotedMessage *quotedMessage;
- (instancetype)initWithTimestamp:(uint64_t)timestamp; - (instancetype)initInteractionWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread NS_UNAVAILABLE;
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(nullable TSThread *)thread; - (instancetype)initMessageWithTimestamp:(uint64_t)timestamp
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body;
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
attachmentIds:(NSArray<NSString *> *)attachmentIds;
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
attachmentIds:(NSArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds;
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body messageBody:(nullable NSString *)body
attachmentIds:(NSArray<NSString *> *)attachmentIds attachmentIds:(NSArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds expiresInSeconds:(uint32_t)expiresInSeconds
expireStartedAt:(uint64_t)expireStartedAt NS_DESIGNATED_INITIALIZER; expireStartedAt:(uint64_t)expireStartedAt
quotedMessage:(nullable TSQuotedMessage *)quotedMessage NS_DESIGNATED_INITIALIZER;
- (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; - (nullable instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;

View file

@ -16,6 +16,8 @@ NS_ASSUME_NONNULL_BEGIN
static const NSUInteger OWSMessageSchemaVersion = 4; static const NSUInteger OWSMessageSchemaVersion = 4;
#pragma mark -
@interface TSMessage () @interface TSMessage ()
@property (nonatomic, nullable) NSString *body; @property (nonatomic, nullable) NSString *body;
@ -48,63 +50,23 @@ static const NSUInteger OWSMessageSchemaVersion = 4;
// they were received & decrypted, not by when they were sent. // they were received & decrypted, not by when they were sent.
@property (nonatomic) uint64_t receivedAtTimestamp; @property (nonatomic) uint64_t receivedAtTimestamp;
@property (nonatomic, nullable) TSQuotedMessage *quotedMessage;
@end @end
#pragma mark - #pragma mark -
@implementation TSMessage @implementation TSMessage
- (instancetype)initWithTimestamp:(uint64_t)timestamp - (instancetype)initMessageWithTimestamp:(uint64_t)timestamp
{
return [self initWithTimestamp:timestamp inThread:nil messageBody:nil];
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(nullable TSThread *)thread
{
return [self initWithTimestamp:timestamp inThread:thread messageBody:nil attachmentIds:@[]];
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
{
return [self initWithTimestamp:timestamp inThread:thread messageBody:body attachmentIds:@[]];
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
attachmentIds:(NSArray<NSString *> *)attachmentIds
{
return [self initWithTimestamp:timestamp
inThread:thread
messageBody:body
attachmentIds:attachmentIds
expiresInSeconds:0];
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
attachmentIds:(NSArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds
{
return [self initWithTimestamp:timestamp
inThread:thread
messageBody:body
attachmentIds:attachmentIds
expiresInSeconds:expiresInSeconds
expireStartedAt:0];
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body messageBody:(nullable NSString *)body
attachmentIds:(NSArray<NSString *> *)attachmentIds attachmentIds:(NSArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds expiresInSeconds:(uint32_t)expiresInSeconds
expireStartedAt:(uint64_t)expireStartedAt expireStartedAt:(uint64_t)expireStartedAt
quotedMessage:(nullable TSQuotedMessage *)quotedMessage
{ {
self = [super initWithTimestamp:timestamp inThread:thread]; self = [super initInteractionWithTimestamp:timestamp inThread:thread];
if (!self) { if (!self) {
return self; return self;
@ -118,6 +80,7 @@ static const NSUInteger OWSMessageSchemaVersion = 4;
_expireStartedAt = expireStartedAt; _expireStartedAt = expireStartedAt;
[self updateExpiresAt]; [self updateExpiresAt];
_receivedAtTimestamp = [NSDate ows_millisecondTimeStamp]; _receivedAtTimestamp = [NSDate ows_millisecondTimeStamp];
_quotedMessage = quotedMessage;
return self; return self;
} }

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "TSMessage.h" #import "TSMessage.h"
@ -37,49 +37,23 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) {
@interface TSOutgoingMessage : TSMessage @interface TSOutgoingMessage : TSMessage
- (instancetype)initWithTimestamp:(uint64_t)timestamp; - (instancetype)initMessageWithTimestamp:(uint64_t)timestamp
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(nullable TSThread *)thread;
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body;
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
groupMetaMessage:(TSGroupMetaMessage)groupMetaMessage;
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body messageBody:(nullable NSString *)body
attachmentIds:(NSMutableArray<NSString *> *)attachmentIds; attachmentIds:(NSArray<NSString *> *)attachmentIds
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
attachmentIds:(NSMutableArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds;
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)messageBody
isVoiceMessage:(BOOL)isVoiceMessage
expiresInSeconds:(uint32_t)expiresInSeconds;
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
attachmentIds:(NSMutableArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds expiresInSeconds:(uint32_t)expiresInSeconds
expireStartedAt:(uint64_t)expireStartedAt; expireStartedAt:(uint64_t)expireStartedAt
quotedMessage:(nullable TSQuotedMessage *)quotedMessage NS_UNAVAILABLE;
- (instancetype)initWithTimestamp:(uint64_t)timestamp - (instancetype)initOutgoingMessageWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body messageBody:(nullable NSString *)body
attachmentIds:(NSMutableArray<NSString *> *)attachmentIds attachmentIds:(NSMutableArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds expiresInSeconds:(uint32_t)expiresInSeconds
expireStartedAt:(uint64_t)expireStartedAt expireStartedAt:(uint64_t)expireStartedAt
groupMetaMessage:(TSGroupMetaMessage)groupMetaMessage NS_DESIGNATED_INITIALIZER; isVoiceMessage:(BOOL)isVoiceMessage
groupMetaMessage:(TSGroupMetaMessage)groupMetaMessage
quotedMessage:(nullable TSQuotedMessage *)quotedMessage NS_DESIGNATED_INITIALIZER;
- (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER; - (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;

View file

@ -11,6 +11,7 @@
#import "TSAttachmentStream.h" #import "TSAttachmentStream.h"
#import "TSContactThread.h" #import "TSContactThread.h"
#import "TSGroupThread.h" #import "TSGroupThread.h"
#import "TSQuotedMessage.h"
#import "TextSecureKitEnv.h" #import "TextSecureKitEnv.h"
#import <YapDatabase/YapDatabase.h> #import <YapDatabase/YapDatabase.h>
#import <YapDatabase/YapDatabaseTransaction.h> #import <YapDatabase/YapDatabaseTransaction.h>
@ -74,117 +75,23 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
return self; return self;
} }
- (instancetype)initWithTimestamp:(uint64_t)timestamp - (instancetype)initOutgoingMessageWithTimestamp:(uint64_t)timestamp
{
return [self initWithTimestamp:timestamp inThread:nil];
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(nullable TSThread *)thread
{
return [self initWithTimestamp:timestamp inThread:thread messageBody:nil];
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
{
return [self initWithTimestamp:timestamp
inThread:thread
messageBody:body
attachmentIds:[NSMutableArray new]
expiresInSeconds:0];
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
attachmentIds:(NSMutableArray<NSString *> *)attachmentIds
{
return [self initWithTimestamp:timestamp
inThread:thread
messageBody:body
attachmentIds:attachmentIds
expiresInSeconds:0];
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
attachmentIds:(NSMutableArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds
{
return [self initWithTimestamp:timestamp
inThread:thread
messageBody:body
attachmentIds:attachmentIds
expiresInSeconds:expiresInSeconds
expireStartedAt:0];
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)messageBody
isVoiceMessage:(BOOL)isVoiceMessage
expiresInSeconds:(uint32_t)expiresInSeconds
{
self = [self initWithTimestamp:timestamp
inThread:thread
messageBody:messageBody
attachmentIds:[NSMutableArray new]
expiresInSeconds:expiresInSeconds
expireStartedAt:0];
if (self) {
_isVoiceMessage = isVoiceMessage;
}
return self;
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body messageBody:(nullable NSString *)body
attachmentIds:(NSMutableArray<NSString *> *)attachmentIds attachmentIds:(NSMutableArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds expiresInSeconds:(uint32_t)expiresInSeconds
expireStartedAt:(uint64_t)expireStartedAt expireStartedAt:(uint64_t)expireStartedAt
isVoiceMessage:(BOOL)isVoiceMessage
groupMetaMessage:(TSGroupMetaMessage)groupMetaMessage
quotedMessage:(nullable TSQuotedMessage *)quotedMessage
{ {
TSGroupMetaMessage groupMetaMessage self = [super initMessageWithTimestamp:timestamp
= ([thread isKindOfClass:[TSGroupThread class]] ? TSGroupMessageDeliver : TSGroupMessageNone);
return [self initWithTimestamp:timestamp
inThread:thread inThread:thread
messageBody:body messageBody:body
attachmentIds:attachmentIds attachmentIds:attachmentIds
expiresInSeconds:expiresInSeconds expiresInSeconds:expiresInSeconds
expireStartedAt:expireStartedAt expireStartedAt:expireStartedAt
groupMetaMessage:groupMetaMessage]; quotedMessage:quotedMessage];
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
groupMetaMessage:(TSGroupMetaMessage)groupMetaMessage
{
return [self initWithTimestamp:timestamp
inThread:thread
messageBody:@""
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
groupMetaMessage:groupMetaMessage];
}
- (instancetype)initWithTimestamp:(uint64_t)timestamp
inThread:(nullable TSThread *)thread
messageBody:(nullable NSString *)body
attachmentIds:(NSMutableArray<NSString *> *)attachmentIds
expiresInSeconds:(uint32_t)expiresInSeconds
expireStartedAt:(uint64_t)expireStartedAt
groupMetaMessage:(TSGroupMetaMessage)groupMetaMessage
{
self = [super initWithTimestamp:timestamp
inThread:thread
messageBody:body
attachmentIds:attachmentIds
expiresInSeconds:expiresInSeconds
expireStartedAt:expireStartedAt];
if (!self) { if (!self) {
return self; return self;
} }
@ -193,6 +100,7 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
_sentRecipients = [NSArray new]; _sentRecipients = [NSArray new];
_hasSyncedTranscript = NO; _hasSyncedTranscript = NO;
_groupMetaMessage = groupMetaMessage; _groupMetaMessage = groupMetaMessage;
_isVoiceMessage = isVoiceMessage;
_attachmentFilenameMap = [NSMutableDictionary new]; _attachmentFilenameMap = [NSMutableDictionary new];
@ -498,6 +406,44 @@ NSString *const kTSOutgoingMessageSentRecipientAll = @"kTSOutgoingMessageSentRec
OWSSignalServiceProtosDataMessageBuilder *builder = [self dataMessageBuilder]; OWSSignalServiceProtosDataMessageBuilder *builder = [self dataMessageBuilder];
[builder setTimestamp:self.timestamp]; [builder setTimestamp:self.timestamp];
[builder addLocalProfileKeyIfNecessary:self.thread recipientId:recipientId]; [builder addLocalProfileKeyIfNecessary:self.thread recipientId:recipientId];
if (self.quotedMessage) {
OWSSignalServiceProtosDataMessageQuoteBuilder *quoteBuilder =
[OWSSignalServiceProtosDataMessageQuoteBuilder new];
[quoteBuilder setId:self.quotedMessage.timestamp];
[quoteBuilder setAuthor:self.quotedMessage.authorId];
BOOL hasQuotedText = NO;
BOOL hasQuotedAttachment = NO;
if (self.quotedMessage.body.length > 0) {
[quoteBuilder setText:self.quotedMessage.body];
hasQuotedText = YES;
}
if (self.quotedMessage.contentType.length > 0) {
OWSSignalServiceProtosAttachmentPointerBuilder *attachmentBuilder =
[OWSSignalServiceProtosAttachmentPointerBuilder new];
if (self.quotedMessage.thumbnailData.length > 0) {
[attachmentBuilder setThumbnail:self.quotedMessage.thumbnailData];
}
if (self.quotedMessage.sourceFilename.length > 0) {
[attachmentBuilder setFileName:self.quotedMessage.sourceFilename];
}
[attachmentBuilder setContentType:self.quotedMessage.contentType];
[quoteBuilder setAttachmentBuilder:attachmentBuilder];
hasQuotedAttachment = YES;
}
if (hasQuotedText || hasQuotedAttachment) {
[builder setQuoteBuilder:quoteBuilder];
} else {
OWSFail(@"%@ Invalid quoted message data.", self.logTag);
}
}
return [builder build]; return [builder build];
} }

View file

@ -0,0 +1,39 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import <SignalServiceKit/TSYapDatabaseObject.h>
NS_ASSUME_NONNULL_BEGIN
@interface TSQuotedMessage : TSYapDatabaseObject
@property (nonatomic, readonly) uint64_t timestamp;
@property (nonatomic, readonly) NSString *authorId;
// This property should be set IFF we are quoting a text message.
@property (nullable, nonatomic, readonly) NSString *body;
// This property should be set IFF we are quoting a attachment message.
@property (nullable, nonatomic, readonly) NSString *sourceFilename;
// This property can be set IFF we are quoting a attachment message, but it is optional.
@property (nullable, nonatomic, readonly) NSData *thumbnailData;
// This is a MIME type.
//
// This property should be set IFF we are quoting a attachment message.
@property (nullable, nonatomic, readonly) NSString *contentType;
- (instancetype)init NS_UNAVAILABLE;
- (instancetype)initWithTimestamp:(uint64_t)timestamp
authorId:(NSString *)authorId
body:(NSString *_Nullable)body
sourceFilename:(NSString *_Nullable)sourceFilename
thumbnailData:(NSData *_Nullable)thumbnailData
contentType:(NSString *_Nullable)contentType;
@end
#pragma mark -
NS_ASSUME_NONNULL_END

View file

@ -0,0 +1,38 @@
//
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "TSQuotedMessage.h"
NS_ASSUME_NONNULL_BEGIN
@implementation TSQuotedMessage
- (instancetype)initWithTimestamp:(uint64_t)timestamp
authorId:(NSString *)authorId
body:(NSString *_Nullable)body
sourceFilename:(NSString *_Nullable)sourceFilename
thumbnailData:(NSData *_Nullable)thumbnailData
contentType:(NSString *_Nullable)contentType
{
self = [super initWithUniqueId:[NSUUID UUID].UUIDString];
if (!self) {
return self;
}
OWSAssert(timestamp > 0);
OWSAssert(authorId.length > 0);
_timestamp = timestamp;
_authorId = authorId;
_body = body;
_sourceFilename = sourceFilename;
_thumbnailData = thumbnailData;
_contentType = contentType;
return self;
}
@end
NS_ASSUME_NONNULL_END

View file

@ -41,6 +41,7 @@
#import "TSInfoMessage.h" #import "TSInfoMessage.h"
#import "TSNetworkManager.h" #import "TSNetworkManager.h"
#import "TSOutgoingMessage.h" #import "TSOutgoingMessage.h"
#import "TSQuotedMessage.h"
#import "TextSecureKitEnv.h" #import "TextSecureKitEnv.h"
#import <YapDatabase/YapDatabase.h> #import <YapDatabase/YapDatabase.h>
@ -888,9 +889,16 @@ NS_ASSUME_NONNULL_BEGIN
NSString *updateGroupInfo = NSString *updateGroupInfo =
[gThread.groupModel getInfoStringAboutUpdateTo:gThread.groupModel contactsManager:self.contactsManager]; [gThread.groupModel getInfoStringAboutUpdateTo:gThread.groupModel contactsManager:self.contactsManager];
TSOutgoingMessage *message = [[TSOutgoingMessage alloc] initWithTimestamp:[NSDate ows_millisecondTimeStamp] TSOutgoingMessage *message =
[[TSOutgoingMessage alloc] initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:gThread inThread:gThread
groupMetaMessage:TSGroupMessageUpdate]; messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageUpdate
quotedMessage:nil];
[message updateWithCustomMessage:updateGroupInfo transaction:transaction]; [message updateWithCustomMessage:updateGroupInfo transaction:transaction];
// Only send this group update to the requester. // Only send this group update to the requester.
[message updateWithSingleGroupRecipient:envelope.source transaction:transaction]; [message updateWithSingleGroupRecipient:envelope.source transaction:transaction];
@ -993,19 +1001,24 @@ NS_ASSUME_NONNULL_BEGIN
return nil; return nil;
} }
TSQuotedMessage *_Nullable quotedMessage = [self quotedMessageForDataMessage:dataMessage];
DDLogDebug(@"%@ incoming message from: %@ for group: %@ with timestamp: %lu", DDLogDebug(@"%@ incoming message from: %@ for group: %@ with timestamp: %lu",
self.logTag, self.logTag,
envelopeAddress(envelope), envelopeAddress(envelope),
groupId, groupId,
(unsigned long)timestamp); (unsigned long)timestamp);
TSIncomingMessage *incomingMessage = TSIncomingMessage *incomingMessage =
[[TSIncomingMessage alloc] initWithTimestamp:timestamp [[TSIncomingMessage alloc] initIncomingMessageWithTimestamp:timestamp
inThread:oldGroupThread inThread:oldGroupThread
authorId:envelope.source authorId:envelope.source
sourceDeviceId:envelope.sourceDevice sourceDeviceId:envelope.sourceDevice
messageBody:body messageBody:body
attachmentIds:attachmentIds attachmentIds:attachmentIds
expiresInSeconds:dataMessage.expireTimer]; expiresInSeconds:dataMessage.expireTimer
quotedMessage:quotedMessage];
[self finalizeIncomingMessage:incomingMessage [self finalizeIncomingMessage:incomingMessage
thread:oldGroupThread thread:oldGroupThread
envelope:envelope envelope:envelope
@ -1036,13 +1049,17 @@ NS_ASSUME_NONNULL_BEGIN
transaction:transaction transaction:transaction
relay:envelope.relay]; relay:envelope.relay];
TSIncomingMessage *incomingMessage = [[TSIncomingMessage alloc] initWithTimestamp:timestamp TSQuotedMessage *_Nullable quotedMessage = [self quotedMessageForDataMessage:dataMessage];
TSIncomingMessage *incomingMessage =
[[TSIncomingMessage alloc] initIncomingMessageWithTimestamp:timestamp
inThread:thread inThread:thread
authorId:[thread contactIdentifier] authorId:[thread contactIdentifier]
sourceDeviceId:envelope.sourceDevice sourceDeviceId:envelope.sourceDevice
messageBody:body messageBody:body
attachmentIds:attachmentIds attachmentIds:attachmentIds
expiresInSeconds:dataMessage.expireTimer]; expiresInSeconds:dataMessage.expireTimer
quotedMessage:quotedMessage];
[self finalizeIncomingMessage:incomingMessage [self finalizeIncomingMessage:incomingMessage
thread:thread thread:thread
envelope:envelope envelope:envelope
@ -1053,6 +1070,70 @@ NS_ASSUME_NONNULL_BEGIN
} }
} }
- (TSQuotedMessage *_Nullable)quotedMessageForDataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
{
OWSAssert(dataMessage);
if (!dataMessage.hasQuote) {
return nil;
}
OWSSignalServiceProtosDataMessageQuote *quoteProto = [dataMessage quote];
if (![quoteProto hasId] || [quoteProto id] == 0) {
OWSFail(@"%@ quoted message missing id", self.logTag);
return nil;
}
uint64_t timestamp = [quoteProto id];
if (![quoteProto hasAuthor] || [quoteProto author].length == 0) {
OWSFail(@"%@ quoted message missing author", self.logTag);
return nil;
}
// TODO: We could verify that this is a valid e164 value.
NSString *authorId = [quoteProto author];
NSString *_Nullable body = nil;
BOOL hasText = NO;
BOOL hasAttachment = NO;
if ([quoteProto hasText] && [quoteProto text].length > 0) {
body = [quoteProto text];
hasText = YES;
}
NSString *_Nullable sourceFilename = nil;
NSData *_Nullable thumbnailData = nil;
NSString *_Nullable contentType = nil;
if ([quoteProto hasAttachment]) {
OWSSignalServiceProtosAttachmentPointer *attachmentProto = [quoteProto attachment];
if ([attachmentProto hasContentType] && attachmentProto.contentType.length > 0) {
contentType = attachmentProto.contentType;
if ([attachmentProto hasFileName] && attachmentProto.fileName.length > 0) {
sourceFilename = attachmentProto.fileName;
}
if ([attachmentProto hasThumbnail] && attachmentProto.thumbnail.length > 0) {
thumbnailData = [attachmentProto thumbnail];
}
}
hasAttachment = YES;
}
if (!hasText && !hasAttachment) {
OWSFail(@"%@ quoted message has neither text nor attachment", self.logTag);
return nil;
}
TSQuotedMessage *quotedMessage = [[TSQuotedMessage alloc] initWithTimestamp:timestamp
authorId:authorId
body:body
sourceFilename:sourceFilename
thumbnailData:thumbnailData
contentType:contentType];
return quotedMessage;
}
- (void)finalizeIncomingMessage:(TSIncomingMessage *)incomingMessage - (void)finalizeIncomingMessage:(TSIncomingMessage *)incomingMessage
thread:(TSThread *)thread thread:(TSThread *)thread
envelope:(OWSSignalServiceProtosEnvelope *)envelope envelope:(OWSSignalServiceProtosEnvelope *)envelope
@ -1069,8 +1150,6 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert([TSAccountManager isRegistered]); OWSAssert([TSAccountManager isRegistered]);
NSString *localNumber = [TSAccountManager localNumber]; NSString *localNumber = [TSAccountManager localNumber];
NSString *body = dataMessage.body;
uint64_t timestamp = envelope.timestamp;
if (!thread) { if (!thread) {
OWSFail(@"%@ Can't finalize without thread", self.logTag); OWSFail(@"%@ Can't finalize without thread", self.logTag);

View file

@ -1236,13 +1236,14 @@ NSString *const OWSMessageSenderRateLimitedException = @"RateLimitedException";
// We want the incoming message to appear after the outgoing message. // We want the incoming message to appear after the outgoing message.
TSIncomingMessage *incomingMessage = TSIncomingMessage *incomingMessage =
[[TSIncomingMessage alloc] initWithTimestamp:(outgoingMessage.timestamp + 1) [[TSIncomingMessage alloc] initIncomingMessageWithTimestamp:(outgoingMessage.timestamp + 1)
inThread:cThread inThread:cThread
authorId:[cThread contactIdentifier] authorId:[cThread contactIdentifier]
sourceDeviceId:[OWSDevice currentDeviceId] sourceDeviceId:[OWSDevice currentDeviceId]
messageBody:outgoingMessage.body messageBody:outgoingMessage.body
attachmentIds:attachmentIds attachmentIds:attachmentIds
expiresInSeconds:outgoingMessage.expiresInSeconds]; expiresInSeconds:outgoingMessage.expiresInSeconds
quotedMessage:outgoingMessage.quotedMessage];
[incomingMessage saveWithTransaction:transaction]; [incomingMessage saveWithTransaction:transaction];
}]; }];
} }

View file

@ -4,7 +4,11 @@
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@class TSIncomingMessage;
@class TSOutgoingMessage;
@class TSQuotedMessage;
@class TSThread; @class TSThread;
@class YapDatabaseReadWriteTransaction;
@interface OWSMessageUtils : NSObject @interface OWSMessageUtils : NSObject
@ -17,6 +21,12 @@ NS_ASSUME_NONNULL_BEGIN
- (void)updateApplicationBadgeCount; - (void)updateApplicationBadgeCount;
+ (nullable TSQuotedMessage *)quotedMessageForIncomingMessage:(TSIncomingMessage *)message
transaction:(YapDatabaseReadWriteTransaction *)transaction;
+ (nullable TSQuotedMessage *)quotedMessageForOutgoingMessage:(TSOutgoingMessage *)message
transaction:(YapDatabaseReadWriteTransaction *)transaction;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View file

@ -5,8 +5,16 @@
#import "OWSMessageUtils.h" #import "OWSMessageUtils.h"
#import "AppContext.h" #import "AppContext.h"
#import "OWSPrimaryStorage.h" #import "OWSPrimaryStorage.h"
#import "TSAccountManager.h"
#import "TSAttachment.h"
#import "TSAttachmentStream.h"
#import "TSDatabaseView.h" #import "TSDatabaseView.h"
#import "TSIncomingMessage.h"
#import "TSMessage.h"
#import "TSOutgoingMessage.h"
#import "TSQuotedMessage.h"
#import "TSThread.h" #import "TSThread.h"
#import "UIImage+OWS.h"
#import <YapDatabase/YapDatabase.h> #import <YapDatabase/YapDatabase.h>
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN
@ -94,6 +102,138 @@ NS_ASSUME_NONNULL_BEGIN
return numberOfItems; return numberOfItems;
} }
+ (nullable TSQuotedMessage *)quotedMessageForIncomingMessage:(TSIncomingMessage *)message
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(message);
OWSAssert(transaction);
return [self quotedMessageForMessage:message
authorId:message.authorId
thread:[message threadWithTransaction:transaction]
transaction:transaction];
}
+ (nullable TSQuotedMessage *)quotedMessageForOutgoingMessage:(TSOutgoingMessage *)message
transaction:(YapDatabaseReadWriteTransaction *)transaction
{
OWSAssert(message);
OWSAssert(transaction);
return [self quotedMessageForMessage:message
authorId:TSAccountManager.localNumber
thread:[message threadWithTransaction:transaction]
transaction:transaction];
}
+ (nullable TSQuotedMessage *)quotedMessageForMessage:(TSMessage *)message
authorId:(NSString *)authorId
thread:(TSThread *)thread
transaction:(YapDatabaseReadTransaction *)transaction
{
OWSAssert(message);
OWSAssert(authorId.length > 0);
OWSAssert(thread);
OWSAssert(transaction);
uint64_t timestamp = message.timestamp;
NSString *_Nullable body = message.body;
BOOL hasText = body.length > 0;
BOOL hasAttachment = NO;
NSString *_Nullable sourceFilename = nil;
NSData *_Nullable thumbnailData = nil;
NSString *_Nullable contentType = nil;
if (message.attachmentIds.count > 0) {
NSString *attachmentId = message.attachmentIds[0];
TSAttachment *_Nullable attachment =
[TSAttachment fetchObjectWithUniqueID:attachmentId transaction:transaction];
if (attachment) {
sourceFilename = attachment.sourceFilename;
contentType = attachment.contentType;
// Try to generate a thumbnail, if possible.
thumbnailData = [self thumbnailDataForAttachment:attachment];
hasAttachment = YES;
}
}
if (!hasText && !hasAttachment) {
OWSFail(@"%@ quoted message has neither text nor attachment", self.logTag);
return nil;
}
TSQuotedMessage *quotedMessage = [[TSQuotedMessage alloc] initWithTimestamp:timestamp
authorId:authorId
body:body
sourceFilename:sourceFilename
thumbnailData:thumbnailData
contentType:contentType];
return quotedMessage;
}
+ (nullable NSData *)thumbnailDataForAttachment:(TSAttachment *)attachment
{
OWSAssert(attachment);
// Try to generate a thumbnail, if possible.
if (![attachment isKindOfClass:[TSAttachmentStream class]]) {
return nil;
}
TSAttachmentStream *attachmentStream = (TSAttachmentStream *)attachment;
UIImage *_Nullable attachmentImage = [attachmentStream image];
if (!attachmentImage) {
return nil;
}
CGSize attachmentImageSizePx;
attachmentImageSizePx.width = CGImageGetWidth(attachmentImage.CGImage);
attachmentImageSizePx.height = CGImageGetHeight(attachmentImage.CGImage);
if (attachmentImageSizePx.width <= 0 || attachmentImageSizePx.height <= 0) {
DDLogError(@"%@ attachment thumbnail has invalid size.", self.logTag);
return nil;
}
const int kMaxThumbnailSizePx = 100;
// Try to resize image to thumbnail if necessary.
if (attachmentImageSizePx.width > kMaxThumbnailSizePx || attachmentImageSizePx.height > kMaxThumbnailSizePx) {
const CGFloat widthFactor = kMaxThumbnailSizePx / attachmentImageSizePx.width;
const CGFloat heightFactor = kMaxThumbnailSizePx / attachmentImageSizePx.height;
const CGFloat scalingFactor = MIN(widthFactor, heightFactor);
const CGFloat scaledWidthPx = (CGFloat)round(attachmentImageSizePx.width * scalingFactor);
const CGFloat scaledHeightPx = (CGFloat)round(attachmentImageSizePx.height * scalingFactor);
if (scaledWidthPx <= 0 || scaledHeightPx <= 0) {
DDLogError(@"%@ can't determined desired size for attachment thumbnail.", self.logTag);
return nil;
}
if (scaledWidthPx > 0 && scaledHeightPx > 0) {
attachmentImage = [attachmentImage resizedImageToSize:CGSizeMake(scaledWidthPx, scaledHeightPx)];
if (!attachmentImage) {
DDLogError(@"%@ attachment thumbnail could not be resized.", self.logTag);
return nil;
}
attachmentImageSizePx.width = CGImageGetWidth(attachmentImage.CGImage);
attachmentImageSizePx.height = CGImageGetHeight(attachmentImage.CGImage);
}
}
if (attachmentImageSizePx.width <= 0 || attachmentImageSizePx.height <= 0) {
DDLogError(@"%@ resized attachment thumbnail has invalid size.", self.logTag);
return nil;
}
NSData *_Nullable attachmentImageData = UIImagePNGRepresentation(attachmentImage);
if (!attachmentImage) {
OWSFail(@"%@ attachment thumbnail could not be written to PNG.", self.logTag);
return nil;
}
return attachmentImageData;
}
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSOutgoingCallMessage.h" #import "OWSOutgoingCallMessage.h"
@ -18,13 +18,19 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSOutgoingCallMessage @implementation OWSOutgoingCallMessage
//@synthesize thread = _thread;
- (instancetype)initWithThread:(TSThread *)thread - (instancetype)initWithThread:(TSThread *)thread
{ {
// These records aren't saved, but their timestamp is used in the event // These records aren't saved, but their timestamp is used in the event
// of a failing message send to insert the error at the appropriate place. // of a failing message send to insert the error at the appropriate place.
self = [super initWithTimestamp:[NSDate ows_millisecondTimeStamp] inThread:thread]; self = [super initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:thread
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageNone
quotedMessage:nil];
if (!self) { if (!self) {
return self; return self;
} }

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSOutgoingNullMessage.h" #import "OWSOutgoingNullMessage.h"
@ -17,13 +17,22 @@ NS_ASSUME_NONNULL_BEGIN
@end @end
#pragma mark -
@implementation OWSOutgoingNullMessage @implementation OWSOutgoingNullMessage
- (instancetype)initWithContactThread:(TSContactThread *)contactThread - (instancetype)initWithContactThread:(TSContactThread *)contactThread
verificationStateSyncMessage:(OWSVerificationStateSyncMessage *)verificationStateSyncMessage verificationStateSyncMessage:(OWSVerificationStateSyncMessage *)verificationStateSyncMessage
{ {
self = [super initWithTimestamp:[NSDate ows_millisecondTimeStamp] self = [super initOutgoingMessageWithTimestamp:[NSDate ows_millisecondTimeStamp]
inThread:contactThread]; inThread:contactThread
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageNone
quotedMessage:nil];
if (!self) { if (!self) {
return self; return self;
} }

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "TSOutgoingMessage.h" #import "TSOutgoingMessage.h"
@ -8,6 +8,8 @@ NS_ASSUME_NONNULL_BEGIN
@interface OWSProfileKeyMessage : TSOutgoingMessage @interface OWSProfileKeyMessage : TSOutgoingMessage
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(nullable TSThread *)thread NS_DESIGNATED_INITIALIZER;
@end @end
NS_ASSUME_NONNULL_END NS_ASSUME_NONNULL_END

View file

@ -12,6 +12,19 @@ NS_ASSUME_NONNULL_BEGIN
@implementation OWSProfileKeyMessage @implementation OWSProfileKeyMessage
- (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(nullable TSThread *)thread
{
return [super initOutgoingMessageWithTimestamp:timestamp
inThread:thread
messageBody:nil
attachmentIds:[NSMutableArray new]
expiresInSeconds:0
expireStartedAt:0
isVoiceMessage:NO
groupMetaMessage:TSGroupMessageNone
quotedMessage:nil];
}
- (BOOL)shouldBeSaved - (BOOL)shouldBeSaved
{ {
return NO; return NO;

View file

@ -1,4 +1,6 @@
// Generated by the protocol buffer compiler. DO NOT EDIT! //
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import <ProtocolBuffers/ProtocolBuffers.h> #import <ProtocolBuffers/ProtocolBuffers.h>
@ -26,6 +28,8 @@
@class OWSSignalServiceProtosContentBuilder; @class OWSSignalServiceProtosContentBuilder;
@class OWSSignalServiceProtosDataMessage; @class OWSSignalServiceProtosDataMessage;
@class OWSSignalServiceProtosDataMessageBuilder; @class OWSSignalServiceProtosDataMessageBuilder;
@class OWSSignalServiceProtosDataMessageQuote;
@class OWSSignalServiceProtosDataMessageQuoteBuilder;
@class OWSSignalServiceProtosEnvelope; @class OWSSignalServiceProtosEnvelope;
@class OWSSignalServiceProtosEnvelopeBuilder; @class OWSSignalServiceProtosEnvelopeBuilder;
@class OWSSignalServiceProtosGroupContext; @class OWSSignalServiceProtosGroupContext;
@ -101,7 +105,6 @@
@class PBUninterpretedOptionNamePart; @class PBUninterpretedOptionNamePart;
@class PBUninterpretedOptionNamePartBuilder; @class PBUninterpretedOptionNamePartBuilder;
typedef NS_ENUM(SInt32, OWSSignalServiceProtosEnvelopeType) { typedef NS_ENUM(SInt32, OWSSignalServiceProtosEnvelopeType) {
OWSSignalServiceProtosEnvelopeTypeUnknown = 0, OWSSignalServiceProtosEnvelopeTypeUnknown = 0,
OWSSignalServiceProtosEnvelopeTypeCiphertext = 1, OWSSignalServiceProtosEnvelopeTypeCiphertext = 1,
@ -800,17 +803,20 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
#define DataMessage_expireTimer @"expireTimer" #define DataMessage_expireTimer @"expireTimer"
#define DataMessage_profileKey @"profileKey" #define DataMessage_profileKey @"profileKey"
#define DataMessage_timestamp @"timestamp" #define DataMessage_timestamp @"timestamp"
#define DataMessage_quote @"quote"
@interface OWSSignalServiceProtosDataMessage : PBGeneratedMessage<GeneratedMessageProtocol> { @interface OWSSignalServiceProtosDataMessage : PBGeneratedMessage<GeneratedMessageProtocol> {
@private @private
BOOL hasTimestamp_:1; BOOL hasTimestamp_:1;
BOOL hasBody_:1; BOOL hasBody_:1;
BOOL hasGroup_:1; BOOL hasGroup_:1;
BOOL hasQuote_ : 1;
BOOL hasProfileKey_:1; BOOL hasProfileKey_:1;
BOOL hasFlags_:1; BOOL hasFlags_:1;
BOOL hasExpireTimer_:1; BOOL hasExpireTimer_:1;
UInt64 timestamp; UInt64 timestamp;
NSString* body; NSString* body;
OWSSignalServiceProtosGroupContext* group; OWSSignalServiceProtosGroupContext* group;
OWSSignalServiceProtosDataMessageQuote *quote;
NSData* profileKey; NSData* profileKey;
UInt32 flags; UInt32 flags;
UInt32 expireTimer; UInt32 expireTimer;
@ -822,6 +828,7 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
- (BOOL) hasExpireTimer; - (BOOL) hasExpireTimer;
- (BOOL) hasProfileKey; - (BOOL) hasProfileKey;
- (BOOL) hasTimestamp; - (BOOL) hasTimestamp;
- (BOOL)hasQuote;
@property (readonly, strong) NSString* body; @property (readonly, strong) NSString* body;
@property (readonly, strong) NSArray<OWSSignalServiceProtosAttachmentPointer*> * attachments; @property (readonly, strong) NSArray<OWSSignalServiceProtosAttachmentPointer*> * attachments;
@property (readonly, strong) OWSSignalServiceProtosGroupContext* group; @property (readonly, strong) OWSSignalServiceProtosGroupContext* group;
@ -829,6 +836,7 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
@property (readonly) UInt32 expireTimer; @property (readonly) UInt32 expireTimer;
@property (readonly, strong) NSData* profileKey; @property (readonly, strong) NSData* profileKey;
@property (readonly) UInt64 timestamp; @property (readonly) UInt64 timestamp;
@property (readonly, strong) OWSSignalServiceProtosDataMessageQuote *quote;
- (OWSSignalServiceProtosAttachmentPointer*)attachmentsAtIndex:(NSUInteger)index; - (OWSSignalServiceProtosAttachmentPointer*)attachmentsAtIndex:(NSUInteger)index;
+ (instancetype) defaultInstance; + (instancetype) defaultInstance;
@ -849,6 +857,94 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
+ (OWSSignalServiceProtosDataMessage*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry; + (OWSSignalServiceProtosDataMessage*) parseFromCodedInputStream:(PBCodedInputStream*) input extensionRegistry:(PBExtensionRegistry*) extensionRegistry;
@end @end
#define Quote_id @"id"
#define Quote_author @"author"
#define Quote_text @"text"
#define Quote_attachment @"attachment"
@interface OWSSignalServiceProtosDataMessageQuote : PBGeneratedMessage <GeneratedMessageProtocol> {
@private
BOOL hasId_ : 1;
BOOL hasAuthor_ : 1;
BOOL hasText_ : 1;
BOOL hasAttachment_ : 1;
UInt64 id;
NSString *author;
NSString *text;
OWSSignalServiceProtosAttachmentPointer *attachment;
}
- (BOOL)hasId;
- (BOOL)hasAuthor;
- (BOOL)hasText;
- (BOOL)hasAttachment;
@property (readonly) UInt64 id;
@property (readonly, strong) NSString *author;
@property (readonly, strong) NSString *text;
@property (readonly, strong) OWSSignalServiceProtosAttachmentPointer *attachment;
+ (instancetype)defaultInstance;
- (instancetype)defaultInstance;
- (BOOL)isInitialized;
- (void)writeToCodedOutputStream:(PBCodedOutputStream *)output;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)builder;
+ (OWSSignalServiceProtosDataMessageQuoteBuilder *)builder;
+ (OWSSignalServiceProtosDataMessageQuoteBuilder *)builderWithPrototype:
(OWSSignalServiceProtosDataMessageQuote *)prototype;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)toBuilder;
+ (OWSSignalServiceProtosDataMessageQuote *)parseFromData:(NSData *)data;
+ (OWSSignalServiceProtosDataMessageQuote *)parseFromData:(NSData *)data
extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
+ (OWSSignalServiceProtosDataMessageQuote *)parseFromInputStream:(NSInputStream *)input;
+ (OWSSignalServiceProtosDataMessageQuote *)parseFromInputStream:(NSInputStream *)input
extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
+ (OWSSignalServiceProtosDataMessageQuote *)parseFromCodedInputStream:(PBCodedInputStream *)input;
+ (OWSSignalServiceProtosDataMessageQuote *)parseFromCodedInputStream:(PBCodedInputStream *)input
extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
@end
@interface OWSSignalServiceProtosDataMessageQuoteBuilder : PBGeneratedMessageBuilder {
@private
OWSSignalServiceProtosDataMessageQuote *resultQuote;
}
- (OWSSignalServiceProtosDataMessageQuote *)defaultInstance;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)clear;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)clone;
- (OWSSignalServiceProtosDataMessageQuote *)build;
- (OWSSignalServiceProtosDataMessageQuote *)buildPartial;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)mergeFrom:(OWSSignalServiceProtosDataMessageQuote *)other;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)mergeFromCodedInputStream:(PBCodedInputStream *)input;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)mergeFromCodedInputStream:(PBCodedInputStream *)input
extensionRegistry:(PBExtensionRegistry *)extensionRegistry;
- (BOOL)hasId;
- (UInt64)id;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)setId:(UInt64)value;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)clearId;
- (BOOL)hasAuthor;
- (NSString *)author;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)setAuthor:(NSString *)value;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)clearAuthor;
- (BOOL)hasText;
- (NSString *)text;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)setText:(NSString *)value;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)clearText;
- (BOOL)hasAttachment;
- (OWSSignalServiceProtosAttachmentPointer *)attachment;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)setAttachment:(OWSSignalServiceProtosAttachmentPointer *)value;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)setAttachmentBuilder:
(OWSSignalServiceProtosAttachmentPointerBuilder *)builderForValue;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)mergeAttachment:(OWSSignalServiceProtosAttachmentPointer *)value;
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)clearAttachment;
@end
@interface OWSSignalServiceProtosDataMessageBuilder : PBGeneratedMessageBuilder { @interface OWSSignalServiceProtosDataMessageBuilder : PBGeneratedMessageBuilder {
@private @private
OWSSignalServiceProtosDataMessage* resultDataMessage; OWSSignalServiceProtosDataMessage* resultDataMessage;
@ -903,6 +999,14 @@ NSString *NSStringFromOWSSignalServiceProtosGroupContextType(OWSSignalServicePro
- (UInt64) timestamp; - (UInt64) timestamp;
- (OWSSignalServiceProtosDataMessageBuilder*) setTimestamp:(UInt64) value; - (OWSSignalServiceProtosDataMessageBuilder*) setTimestamp:(UInt64) value;
- (OWSSignalServiceProtosDataMessageBuilder*) clearTimestamp; - (OWSSignalServiceProtosDataMessageBuilder*) clearTimestamp;
- (BOOL)hasQuote;
- (OWSSignalServiceProtosDataMessageQuote *)quote;
- (OWSSignalServiceProtosDataMessageBuilder *)setQuote:(OWSSignalServiceProtosDataMessageQuote *)value;
- (OWSSignalServiceProtosDataMessageBuilder *)setQuoteBuilder:
(OWSSignalServiceProtosDataMessageQuoteBuilder *)builderForValue;
- (OWSSignalServiceProtosDataMessageBuilder *)mergeQuote:(OWSSignalServiceProtosDataMessageQuote *)value;
- (OWSSignalServiceProtosDataMessageBuilder *)clearQuote;
@end @end
#define NullMessage_padding @"padding" #define NullMessage_padding @"padding"

View file

@ -1,6 +1,9 @@
// Generated by the protocol buffer compiler. DO NOT EDIT! //
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
//
#import "OWSSignalServiceProtos.pb.h" #import "OWSSignalServiceProtos.pb.h"
// @@protoc_insertion_point(imports) // @@protoc_insertion_point(imports)
@implementation OWSSignalServiceProtosOwssignalServiceProtosRoot @implementation OWSSignalServiceProtosOwssignalServiceProtosRoot
@ -2922,6 +2925,7 @@ static OWSSignalServiceProtosCallMessageHangup* defaultOWSSignalServiceProtosCal
@property UInt32 expireTimer; @property UInt32 expireTimer;
@property (strong) NSData* profileKey; @property (strong) NSData* profileKey;
@property UInt64 timestamp; @property UInt64 timestamp;
@property (strong) OWSSignalServiceProtosDataMessageQuote *quote;
@end @end
@implementation OWSSignalServiceProtosDataMessage @implementation OWSSignalServiceProtosDataMessage
@ -2970,6 +2974,15 @@ static OWSSignalServiceProtosCallMessageHangup* defaultOWSSignalServiceProtosCal
hasTimestamp_ = !!_value_; hasTimestamp_ = !!_value_;
} }
@synthesize timestamp; @synthesize timestamp;
- (BOOL)hasQuote
{
return !!hasQuote_;
}
- (void)setHasQuote:(BOOL)_value_
{
hasQuote_ = !!_value_;
}
@synthesize quote;
- (instancetype) init { - (instancetype) init {
if ((self = [super init])) { if ((self = [super init])) {
self.body = @""; self.body = @"";
@ -2978,6 +2991,7 @@ static OWSSignalServiceProtosCallMessageHangup* defaultOWSSignalServiceProtosCal
self.expireTimer = 0; self.expireTimer = 0;
self.profileKey = [NSData data]; self.profileKey = [NSData data];
self.timestamp = 0L; self.timestamp = 0L;
self.quote = [OWSSignalServiceProtosDataMessageQuote defaultInstance];
} }
return self; return self;
} }
@ -3024,6 +3038,9 @@ static OWSSignalServiceProtosDataMessage* defaultOWSSignalServiceProtosDataMessa
if (self.hasTimestamp) { if (self.hasTimestamp) {
[output writeUInt64:7 value:self.timestamp]; [output writeUInt64:7 value:self.timestamp];
} }
if (self.hasQuote) {
[output writeMessage:8 value:self.quote];
}
[self.unknownFields writeToCodedOutputStream:output]; [self.unknownFields writeToCodedOutputStream:output];
} }
- (SInt32) serializedSize { - (SInt32) serializedSize {
@ -3054,6 +3071,9 @@ static OWSSignalServiceProtosDataMessage* defaultOWSSignalServiceProtosDataMessa
if (self.hasTimestamp) { if (self.hasTimestamp) {
size_ += computeUInt64Size(7, self.timestamp); size_ += computeUInt64Size(7, self.timestamp);
} }
if (self.hasQuote) {
size_ += computeMessageSize(8, self.quote);
}
size_ += self.unknownFields.serializedSize; size_ += self.unknownFields.serializedSize;
memoizedSerializedSize = size_; memoizedSerializedSize = size_;
return size_; return size_;
@ -3116,6 +3136,11 @@ static OWSSignalServiceProtosDataMessage* defaultOWSSignalServiceProtosDataMessa
if (self.hasTimestamp) { if (self.hasTimestamp) {
[output appendFormat:@"%@%@: %@\n", indent, @"timestamp", [NSNumber numberWithLongLong:self.timestamp]]; [output appendFormat:@"%@%@: %@\n", indent, @"timestamp", [NSNumber numberWithLongLong:self.timestamp]];
} }
if (self.hasQuote) {
[output appendFormat:@"%@%@ {\n", indent, @"quote"];
[self.quote writeDescriptionTo:output withIndent:[NSString stringWithFormat:@"%@ ", indent]];
[output appendFormat:@"%@}\n", indent];
}
[self.unknownFields writeDescriptionTo:output withIndent:indent]; [self.unknownFields writeDescriptionTo:output withIndent:indent];
} }
- (void) storeInDictionary:(NSMutableDictionary *)dictionary { - (void) storeInDictionary:(NSMutableDictionary *)dictionary {
@ -3144,6 +3169,11 @@ static OWSSignalServiceProtosDataMessage* defaultOWSSignalServiceProtosDataMessa
if (self.hasTimestamp) { if (self.hasTimestamp) {
[dictionary setObject: [NSNumber numberWithLongLong:self.timestamp] forKey: @"timestamp"]; [dictionary setObject: [NSNumber numberWithLongLong:self.timestamp] forKey: @"timestamp"];
} }
if (self.hasQuote) {
NSMutableDictionary *messageDictionary = [NSMutableDictionary dictionary];
[self.quote storeInDictionary:messageDictionary];
[dictionary setObject:[NSDictionary dictionaryWithDictionary:messageDictionary] forKey:@"quote"];
}
[self.unknownFields storeInDictionary:dictionary]; [self.unknownFields storeInDictionary:dictionary];
} }
- (BOOL) isEqual:(id)other { - (BOOL) isEqual:(id)other {
@ -3154,21 +3184,18 @@ static OWSSignalServiceProtosDataMessage* defaultOWSSignalServiceProtosDataMessa
return NO; return NO;
} }
OWSSignalServiceProtosDataMessage *otherMessage = other; OWSSignalServiceProtosDataMessage *otherMessage = other;
return return self.hasBody == otherMessage.hasBody && (!self.hasBody || [self.body isEqual:otherMessage.body]) &&
self.hasBody == otherMessage.hasBody && [self.attachmentsArray isEqualToArray:otherMessage.attachmentsArray] && self.hasGroup == otherMessage.hasGroup
(!self.hasBody || [self.body isEqual:otherMessage.body]) && && (!self.hasGroup || [self.group isEqual:otherMessage.group]) && self.hasFlags == otherMessage.hasFlags
[self.attachmentsArray isEqualToArray:otherMessage.attachmentsArray] && && (!self.hasFlags || self.flags == otherMessage.flags) && self.hasExpireTimer == otherMessage.hasExpireTimer
self.hasGroup == otherMessage.hasGroup && && (!self.hasExpireTimer || self.expireTimer == otherMessage.expireTimer)
(!self.hasGroup || [self.group isEqual:otherMessage.group]) && && self.hasProfileKey == otherMessage.hasProfileKey
self.hasFlags == otherMessage.hasFlags && && (!self.hasProfileKey || [self.profileKey isEqual:otherMessage.profileKey])
(!self.hasFlags || self.flags == otherMessage.flags) && && self.hasTimestamp == otherMessage.hasTimestamp
self.hasExpireTimer == otherMessage.hasExpireTimer && && (!self.hasTimestamp || self.timestamp == otherMessage.timestamp) && self.hasQuote == otherMessage.hasQuote
(!self.hasExpireTimer || self.expireTimer == otherMessage.expireTimer) && && (!self.hasQuote || [self.quote isEqual:otherMessage.quote])
self.hasProfileKey == otherMessage.hasProfileKey && && (self.unknownFields == otherMessage.unknownFields
(!self.hasProfileKey || [self.profileKey isEqual:otherMessage.profileKey]) && || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields]));
self.hasTimestamp == otherMessage.hasTimestamp &&
(!self.hasTimestamp || self.timestamp == otherMessage.timestamp) &&
(self.unknownFields == otherMessage.unknownFields || (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields]));
} }
- (NSUInteger) hash { - (NSUInteger) hash {
__block NSUInteger hashCode = 7; __block NSUInteger hashCode = 7;
@ -3193,6 +3220,9 @@ static OWSSignalServiceProtosDataMessage* defaultOWSSignalServiceProtosDataMessa
if (self.hasTimestamp) { if (self.hasTimestamp) {
hashCode = hashCode * 31 + [[NSNumber numberWithLongLong:self.timestamp] hash]; hashCode = hashCode * 31 + [[NSNumber numberWithLongLong:self.timestamp] hash];
} }
if (self.hasQuote) {
hashCode = hashCode * 31 + [self.quote hash];
}
hashCode = hashCode * 31 + [self.unknownFields hash]; hashCode = hashCode * 31 + [self.unknownFields hash];
return hashCode; return hashCode;
} }
@ -3221,6 +3251,455 @@ NSString *NSStringFromOWSSignalServiceProtosDataMessageFlags(OWSSignalServicePro
} }
} }
@interface OWSSignalServiceProtosDataMessageQuote ()
@property UInt64 id;
@property (strong) NSString *author;
@property (strong) NSString *text;
@property (strong) OWSSignalServiceProtosAttachmentPointer *attachment;
@end
@implementation OWSSignalServiceProtosDataMessageQuote
- (BOOL)hasId
{
return !!hasId_;
}
- (void)setHasId:(BOOL)_value_
{
hasId_ = !!_value_;
}
@synthesize id;
- (BOOL)hasAuthor
{
return !!hasAuthor_;
}
- (void)setHasAuthor:(BOOL)_value_
{
hasAuthor_ = !!_value_;
}
@synthesize author;
- (BOOL)hasText
{
return !!hasText_;
}
- (void)setHasText:(BOOL)_value_
{
hasText_ = !!_value_;
}
@synthesize text;
- (BOOL)hasAttachment
{
return !!hasAttachment_;
}
- (void)setHasAttachment:(BOOL)_value_
{
hasAttachment_ = !!_value_;
}
@synthesize attachment;
- (instancetype)init
{
if ((self = [super init])) {
self.id = 0L;
self.author = @"";
self.text = @"";
self.attachment = [OWSSignalServiceProtosAttachmentPointer defaultInstance];
}
return self;
}
static OWSSignalServiceProtosDataMessageQuote *defaultOWSSignalServiceProtosDataMessageQuoteInstance = nil;
+ (void)initialize
{
if (self == [OWSSignalServiceProtosDataMessageQuote class]) {
defaultOWSSignalServiceProtosDataMessageQuoteInstance = [[OWSSignalServiceProtosDataMessageQuote alloc] init];
}
}
+ (instancetype)defaultInstance
{
return defaultOWSSignalServiceProtosDataMessageQuoteInstance;
}
- (instancetype)defaultInstance
{
return defaultOWSSignalServiceProtosDataMessageQuoteInstance;
}
- (BOOL)isInitialized
{
return YES;
}
- (void)writeToCodedOutputStream:(PBCodedOutputStream *)output
{
if (self.hasId) {
[output writeUInt64:1 value:self.id];
}
if (self.hasAuthor) {
[output writeString:2 value:self.author];
}
if (self.hasText) {
[output writeString:3 value:self.text];
}
if (self.hasAttachment) {
[output writeMessage:4 value:self.attachment];
}
[self.unknownFields writeToCodedOutputStream:output];
}
- (SInt32)serializedSize
{
__block SInt32 size_ = memoizedSerializedSize;
if (size_ != -1) {
return size_;
}
size_ = 0;
if (self.hasId) {
size_ += computeUInt64Size(1, self.id);
}
if (self.hasAuthor) {
size_ += computeStringSize(2, self.author);
}
if (self.hasText) {
size_ += computeStringSize(3, self.text);
}
if (self.hasAttachment) {
size_ += computeMessageSize(4, self.attachment);
}
size_ += self.unknownFields.serializedSize;
memoizedSerializedSize = size_;
return size_;
}
+ (OWSSignalServiceProtosDataMessageQuote *)parseFromData:(NSData *)data
{
return (OWSSignalServiceProtosDataMessageQuote *)[
[[OWSSignalServiceProtosDataMessageQuote builder] mergeFromData:data] build];
}
+ (OWSSignalServiceProtosDataMessageQuote *)parseFromData:(NSData *)data
extensionRegistry:(PBExtensionRegistry *)extensionRegistry
{
return (OWSSignalServiceProtosDataMessageQuote *)[
[[OWSSignalServiceProtosDataMessageQuote builder] mergeFromData:data extensionRegistry:extensionRegistry]
build];
}
+ (OWSSignalServiceProtosDataMessageQuote *)parseFromInputStream:(NSInputStream *)input
{
return (OWSSignalServiceProtosDataMessageQuote *)[
[[OWSSignalServiceProtosDataMessageQuote builder] mergeFromInputStream:input] build];
}
+ (OWSSignalServiceProtosDataMessageQuote *)parseFromInputStream:(NSInputStream *)input
extensionRegistry:(PBExtensionRegistry *)extensionRegistry
{
return (OWSSignalServiceProtosDataMessageQuote *)[
[[OWSSignalServiceProtosDataMessageQuote builder] mergeFromInputStream:input
extensionRegistry:extensionRegistry] build];
}
+ (OWSSignalServiceProtosDataMessageQuote *)parseFromCodedInputStream:(PBCodedInputStream *)input
{
return (OWSSignalServiceProtosDataMessageQuote *)[
[[OWSSignalServiceProtosDataMessageQuote builder] mergeFromCodedInputStream:input] build];
}
+ (OWSSignalServiceProtosDataMessageQuote *)parseFromCodedInputStream:(PBCodedInputStream *)input
extensionRegistry:(PBExtensionRegistry *)extensionRegistry
{
return (OWSSignalServiceProtosDataMessageQuote *)[
[[OWSSignalServiceProtosDataMessageQuote builder] mergeFromCodedInputStream:input
extensionRegistry:extensionRegistry] build];
}
+ (OWSSignalServiceProtosDataMessageQuoteBuilder *)builder
{
return [[OWSSignalServiceProtosDataMessageQuoteBuilder alloc] init];
}
+ (OWSSignalServiceProtosDataMessageQuoteBuilder *)builderWithPrototype:
(OWSSignalServiceProtosDataMessageQuote *)prototype
{
return [[OWSSignalServiceProtosDataMessageQuote builder] mergeFrom:prototype];
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)builder
{
return [OWSSignalServiceProtosDataMessageQuote builder];
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)toBuilder
{
return [OWSSignalServiceProtosDataMessageQuote builderWithPrototype:self];
}
- (void)writeDescriptionTo:(NSMutableString *)output withIndent:(NSString *)indent
{
if (self.hasId) {
[output appendFormat:@"%@%@: %@\n", indent, @"id", [NSNumber numberWithLongLong:self.id]];
}
if (self.hasAuthor) {
[output appendFormat:@"%@%@: %@\n", indent, @"author", self.author];
}
if (self.hasText) {
[output appendFormat:@"%@%@: %@\n", indent, @"text", self.text];
}
if (self.hasAttachment) {
[output appendFormat:@"%@%@ {\n", indent, @"attachment"];
[self.attachment writeDescriptionTo:output withIndent:[NSString stringWithFormat:@"%@ ", indent]];
[output appendFormat:@"%@}\n", indent];
}
[self.unknownFields writeDescriptionTo:output withIndent:indent];
}
- (void)storeInDictionary:(NSMutableDictionary *)dictionary
{
if (self.hasId) {
[dictionary setObject:[NSNumber numberWithLongLong:self.id] forKey:@"id"];
}
if (self.hasAuthor) {
[dictionary setObject:self.author forKey:@"author"];
}
if (self.hasText) {
[dictionary setObject:self.text forKey:@"text"];
}
if (self.hasAttachment) {
NSMutableDictionary *messageDictionary = [NSMutableDictionary dictionary];
[self.attachment storeInDictionary:messageDictionary];
[dictionary setObject:[NSDictionary dictionaryWithDictionary:messageDictionary] forKey:@"attachment"];
}
[self.unknownFields storeInDictionary:dictionary];
}
- (BOOL)isEqual:(id)other
{
if (other == self) {
return YES;
}
if (![other isKindOfClass:[OWSSignalServiceProtosDataMessageQuote class]]) {
return NO;
}
OWSSignalServiceProtosDataMessageQuote *otherMessage = other;
return self.hasId == otherMessage.hasId && (!self.hasId || self.id == otherMessage.id)
&& self.hasAuthor == otherMessage.hasAuthor && (!self.hasAuthor || [self.author isEqual:otherMessage.author])
&& self.hasText == otherMessage.hasText && (!self.hasText || [self.text isEqual:otherMessage.text])
&& self.hasAttachment == otherMessage.hasAttachment
&& (!self.hasAttachment || [self.attachment isEqual:otherMessage.attachment])
&& (self.unknownFields == otherMessage.unknownFields
|| (self.unknownFields != nil && [self.unknownFields isEqual:otherMessage.unknownFields]));
}
- (NSUInteger)hash
{
__block NSUInteger hashCode = 7;
if (self.hasId) {
hashCode = hashCode * 31 + [[NSNumber numberWithLongLong:self.id] hash];
}
if (self.hasAuthor) {
hashCode = hashCode * 31 + [self.author hash];
}
if (self.hasText) {
hashCode = hashCode * 31 + [self.text hash];
}
if (self.hasAttachment) {
hashCode = hashCode * 31 + [self.attachment hash];
}
hashCode = hashCode * 31 + [self.unknownFields hash];
return hashCode;
}
@end
@interface OWSSignalServiceProtosDataMessageQuoteBuilder ()
@property (strong) OWSSignalServiceProtosDataMessageQuote *resultQuote;
@end
@implementation OWSSignalServiceProtosDataMessageQuoteBuilder
@synthesize resultQuote;
- (instancetype)init
{
if ((self = [super init])) {
self.resultQuote = [[OWSSignalServiceProtosDataMessageQuote alloc] init];
}
return self;
}
- (PBGeneratedMessage *)internalGetResult
{
return resultQuote;
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)clear
{
self.resultQuote = [[OWSSignalServiceProtosDataMessageQuote alloc] init];
return self;
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)clone
{
return [OWSSignalServiceProtosDataMessageQuote builderWithPrototype:resultQuote];
}
- (OWSSignalServiceProtosDataMessageQuote *)defaultInstance
{
return [OWSSignalServiceProtosDataMessageQuote defaultInstance];
}
- (OWSSignalServiceProtosDataMessageQuote *)build
{
[self checkInitialized];
return [self buildPartial];
}
- (OWSSignalServiceProtosDataMessageQuote *)buildPartial
{
OWSSignalServiceProtosDataMessageQuote *returnMe = resultQuote;
self.resultQuote = nil;
return returnMe;
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)mergeFrom:(OWSSignalServiceProtosDataMessageQuote *)other
{
if (other == [OWSSignalServiceProtosDataMessageQuote defaultInstance]) {
return self;
}
if (other.hasId) {
[self setId:other.id];
}
if (other.hasAuthor) {
[self setAuthor:other.author];
}
if (other.hasText) {
[self setText:other.text];
}
if (other.hasAttachment) {
[self mergeAttachment:other.attachment];
}
[self mergeUnknownFields:other.unknownFields];
return self;
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)mergeFromCodedInputStream:(PBCodedInputStream *)input
{
return [self mergeFromCodedInputStream:input extensionRegistry:[PBExtensionRegistry emptyRegistry]];
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)mergeFromCodedInputStream:(PBCodedInputStream *)input
extensionRegistry:(PBExtensionRegistry *)extensionRegistry
{
PBUnknownFieldSetBuilder *unknownFields = [PBUnknownFieldSet builderWithUnknownFields:self.unknownFields];
while (YES) {
SInt32 tag = [input readTag];
switch (tag) {
case 0:
[self setUnknownFields:[unknownFields build]];
return self;
default: {
if (![self parseUnknownField:input
unknownFields:unknownFields
extensionRegistry:extensionRegistry
tag:tag]) {
[self setUnknownFields:[unknownFields build]];
return self;
}
break;
}
case 8: {
[self setId:[input readUInt64]];
break;
}
case 18: {
[self setAuthor:[input readString]];
break;
}
case 26: {
[self setText:[input readString]];
break;
}
case 34: {
OWSSignalServiceProtosAttachmentPointerBuilder *subBuilder =
[OWSSignalServiceProtosAttachmentPointer builder];
if (self.hasAttachment) {
[subBuilder mergeFrom:self.attachment];
}
[input readMessage:subBuilder extensionRegistry:extensionRegistry];
[self setAttachment:[subBuilder buildPartial]];
break;
}
}
}
}
- (BOOL)hasId
{
return resultQuote.hasId;
}
- (UInt64)id
{
return resultQuote.id;
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)setId:(UInt64)value
{
resultQuote.hasId = YES;
resultQuote.id = value;
return self;
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)clearId
{
resultQuote.hasId = NO;
resultQuote.id = 0L;
return self;
}
- (BOOL)hasAuthor
{
return resultQuote.hasAuthor;
}
- (NSString *)author
{
return resultQuote.author;
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)setAuthor:(NSString *)value
{
resultQuote.hasAuthor = YES;
resultQuote.author = value;
return self;
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)clearAuthor
{
resultQuote.hasAuthor = NO;
resultQuote.author = @"";
return self;
}
- (BOOL)hasText
{
return resultQuote.hasText;
}
- (NSString *)text
{
return resultQuote.text;
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)setText:(NSString *)value
{
resultQuote.hasText = YES;
resultQuote.text = value;
return self;
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)clearText
{
resultQuote.hasText = NO;
resultQuote.text = @"";
return self;
}
- (BOOL)hasAttachment
{
return resultQuote.hasAttachment;
}
- (OWSSignalServiceProtosAttachmentPointer *)attachment
{
return resultQuote.attachment;
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)setAttachment:(OWSSignalServiceProtosAttachmentPointer *)value
{
resultQuote.hasAttachment = YES;
resultQuote.attachment = value;
return self;
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)setAttachmentBuilder:
(OWSSignalServiceProtosAttachmentPointerBuilder *)builderForValue
{
return [self setAttachment:[builderForValue build]];
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)mergeAttachment:(OWSSignalServiceProtosAttachmentPointer *)value
{
if (resultQuote.hasAttachment
&& resultQuote.attachment != [OWSSignalServiceProtosAttachmentPointer defaultInstance]) {
resultQuote.attachment = [[[OWSSignalServiceProtosAttachmentPointer builderWithPrototype:resultQuote.attachment]
mergeFrom:value] buildPartial];
} else {
resultQuote.attachment = value;
}
resultQuote.hasAttachment = YES;
return self;
}
- (OWSSignalServiceProtosDataMessageQuoteBuilder *)clearAttachment
{
resultQuote.hasAttachment = NO;
resultQuote.attachment = [OWSSignalServiceProtosAttachmentPointer defaultInstance];
return self;
}
@end
@interface OWSSignalServiceProtosDataMessageBuilder() @interface OWSSignalServiceProtosDataMessageBuilder()
@property (strong) OWSSignalServiceProtosDataMessage* resultDataMessage; @property (strong) OWSSignalServiceProtosDataMessage* resultDataMessage;
@end @end
@ -3284,6 +3763,9 @@ NSString *NSStringFromOWSSignalServiceProtosDataMessageFlags(OWSSignalServicePro
if (other.hasTimestamp) { if (other.hasTimestamp) {
[self setTimestamp:other.timestamp]; [self setTimestamp:other.timestamp];
} }
if (other.hasQuote) {
[self mergeQuote:other.quote];
}
[self mergeUnknownFields:other.unknownFields]; [self mergeUnknownFields:other.unknownFields];
return self; return self;
} }
@ -3340,6 +3822,15 @@ NSString *NSStringFromOWSSignalServiceProtosDataMessageFlags(OWSSignalServicePro
[self setTimestamp:[input readUInt64]]; [self setTimestamp:[input readUInt64]];
break; break;
} }
case 66: {
OWSSignalServiceProtosDataMessageQuoteBuilder *subBuilder = [OWSSignalServiceProtosDataMessageQuote builder];
if (self.hasQuote) {
[subBuilder mergeFrom:self.quote];
}
[input readMessage:subBuilder extensionRegistry:extensionRegistry];
[self setQuote:[subBuilder buildPartial]];
break;
}
} }
} }
} }
@ -3474,6 +3965,44 @@ NSString *NSStringFromOWSSignalServiceProtosDataMessageFlags(OWSSignalServicePro
resultDataMessage.timestamp = 0L; resultDataMessage.timestamp = 0L;
return self; return self;
} }
- (BOOL)hasQuote
{
return resultDataMessage.hasQuote;
}
- (OWSSignalServiceProtosDataMessageQuote *)quote
{
return resultDataMessage.quote;
}
- (OWSSignalServiceProtosDataMessageBuilder *)setQuote:(OWSSignalServiceProtosDataMessageQuote *)value
{
resultDataMessage.hasQuote = YES;
resultDataMessage.quote = value;
return self;
}
- (OWSSignalServiceProtosDataMessageBuilder *)setQuoteBuilder:
(OWSSignalServiceProtosDataMessageQuoteBuilder *)builderForValue
{
return [self setQuote:[builderForValue build]];
}
- (OWSSignalServiceProtosDataMessageBuilder *)mergeQuote:(OWSSignalServiceProtosDataMessageQuote *)value
{
if (resultDataMessage.hasQuote
&& resultDataMessage.quote != [OWSSignalServiceProtosDataMessageQuote defaultInstance]) {
resultDataMessage.quote =
[[[OWSSignalServiceProtosDataMessageQuote builderWithPrototype:resultDataMessage.quote] mergeFrom:value]
buildPartial];
} else {
resultDataMessage.quote = value;
}
resultDataMessage.hasQuote = YES;
return self;
}
- (OWSSignalServiceProtosDataMessageBuilder *)clearQuote
{
resultDataMessage.hasQuote = NO;
resultDataMessage.quote = [OWSSignalServiceProtosDataMessageQuote defaultInstance];
return self;
}
@end @end
@interface OWSSignalServiceProtosNullMessage () @interface OWSSignalServiceProtosNullMessage ()

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "OWSReadTracking.h" #import "OWSReadTracking.h"
@ -24,6 +24,8 @@ typedef enum {
@property (nonatomic, readonly) RPRecentCallType callType; @property (nonatomic, readonly) RPRecentCallType callType;
- (instancetype)initInteractionWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread NS_UNAVAILABLE;
- (instancetype)initWithTimestamp:(uint64_t)timestamp - (instancetype)initWithTimestamp:(uint64_t)timestamp
withCallNumber:(NSString *)contactNumber withCallNumber:(NSString *)contactNumber
callType:(RPRecentCallType)callType callType:(RPRecentCallType)callType

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
#import "TSCall.h" #import "TSCall.h"
@ -28,7 +28,7 @@ NSUInteger TSCallCurrentSchemaVersion = 1;
callType:(RPRecentCallType)callType callType:(RPRecentCallType)callType
inThread:(TSContactThread *)thread inThread:(TSContactThread *)thread
{ {
self = [super initWithTimestamp:timestamp inThread:thread]; self = [super initInteractionWithTimestamp:timestamp inThread:thread];
if (!self) { if (!self) {
return self; return self;

View file

@ -1,5 +1,5 @@
// //
// Copyright (c) 2017 Open Whisper Systems. All rights reserved. // Copyright (c) 2018 Open Whisper Systems. All rights reserved.
// //
NS_ASSUME_NONNULL_BEGIN NS_ASSUME_NONNULL_BEGIN