Sketch out "contact share" model.
This commit is contained in:
parent
4b8a2fa8a3
commit
7490a55f61
2
Pods
2
Pods
@ -1 +1 @@
|
||||
Subproject commit 7f6203376010de8838e21a2c22546f10fc24f712
|
||||
Subproject commit 60da392e16648441b23dd3491e14d5bf4c94aaf9
|
||||
@ -13,6 +13,7 @@
|
||||
#import <SignalServiceKit/MIMETypeUtil.h>
|
||||
#import <SignalServiceKit/NSDate+OWS.h>
|
||||
#import <SignalServiceKit/OWSBatchMessageProcessor.h>
|
||||
#import <SignalServiceKit/OWSContactShare+Private.h>
|
||||
#import <SignalServiceKit/OWSDisappearingConfigurationUpdateInfoMessage.h>
|
||||
#import <SignalServiceKit/OWSDisappearingMessagesConfiguration.h>
|
||||
#import <SignalServiceKit/OWSMessageUtils.h>
|
||||
@ -43,36 +44,11 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
return @"Messages";
|
||||
}
|
||||
|
||||
- (nullable OWSTableSection *)sectionForThread:(nullable TSThread *)thread
|
||||
- (NSArray<OWSTableItem *> *)itemsForActions:(NSArray<DebugUIMessagesAction *> *)actions
|
||||
{
|
||||
OWSAssert(thread);
|
||||
|
||||
NSMutableArray<OWSTableItem *> *items = [NSMutableArray new];
|
||||
|
||||
[items addObject:[OWSTableItem itemWithTitle:@"Delete all messages in thread"
|
||||
actionBlock:^{
|
||||
[DebugUIMessages deleteAllMessagesInThread:thread];
|
||||
}]];
|
||||
|
||||
for (DebugUIMessagesAction *action in @[
|
||||
[DebugUIMessages sendMessageVariationsAction:thread],
|
||||
// Send Media
|
||||
[DebugUIMessages sendAllMediaAction:thread],
|
||||
[DebugUIMessages sendRandomMediaAction:thread],
|
||||
// Fake Media
|
||||
[DebugUIMessages fakeAllMediaAction:thread],
|
||||
[DebugUIMessages fakeRandomMediaAction:thread],
|
||||
// Fake Text
|
||||
[DebugUIMessages fakeAllTextAction:thread],
|
||||
[DebugUIMessages fakeRandomTextAction:thread],
|
||||
// Sequences
|
||||
[DebugUIMessages allFakeSequencesAction:thread],
|
||||
// Quoted Replies
|
||||
[DebugUIMessages allQuotedReplyAction:thread],
|
||||
// Exemplary
|
||||
[DebugUIMessages allFakeAction:thread],
|
||||
[DebugUIMessages allFakeBackDatedAction:thread],
|
||||
]) {
|
||||
for (DebugUIMessagesAction *action in actions) {
|
||||
[items addObject:[OWSTableItem itemWithTitle:action.label
|
||||
actionBlock:^{
|
||||
// For "all in group" actions, do each subaction in the group
|
||||
@ -89,6 +65,41 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
}]];
|
||||
}
|
||||
|
||||
return items;
|
||||
}
|
||||
|
||||
- (nullable OWSTableSection *)sectionForThread:(nullable TSThread *)thread
|
||||
{
|
||||
OWSAssert(thread);
|
||||
|
||||
NSMutableArray<OWSTableItem *> *items = [NSMutableArray new];
|
||||
|
||||
[items addObject:[OWSTableItem itemWithTitle:@"Delete all messages in thread"
|
||||
actionBlock:^{
|
||||
[DebugUIMessages deleteAllMessagesInThread:thread];
|
||||
}]];
|
||||
|
||||
[items addObjectsFromArray:[self itemsForActions:@[
|
||||
[DebugUIMessages sendMessageVariationsAction:thread],
|
||||
// Send Media
|
||||
[DebugUIMessages sendAllMediaAction:thread],
|
||||
[DebugUIMessages sendRandomMediaAction:thread],
|
||||
// Fake Media
|
||||
[DebugUIMessages fakeAllMediaAction:thread],
|
||||
[DebugUIMessages fakeRandomMediaAction:thread],
|
||||
// Fake Text
|
||||
[DebugUIMessages fakeAllTextAction:thread],
|
||||
[DebugUIMessages fakeRandomTextAction:thread],
|
||||
// Sequences
|
||||
[DebugUIMessages allFakeSequencesAction:thread],
|
||||
// Quoted Replies
|
||||
[DebugUIMessages allQuotedReplyAction:thread],
|
||||
// Exemplary
|
||||
[DebugUIMessages allFakeAction:thread],
|
||||
[DebugUIMessages allFakeBackDatedAction:thread],
|
||||
[DebugUIMessages allShareContactAction:thread],
|
||||
]]];
|
||||
|
||||
[items addObjectsFromArray:@[
|
||||
|
||||
#pragma mark - Actions
|
||||
@ -809,6 +820,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
isDelivered:YES
|
||||
isRead:NO
|
||||
quotedMessage:nil
|
||||
contactShare:nil
|
||||
transaction:transaction];
|
||||
|
||||
// This is a hack to "back-date" the message.
|
||||
@ -1741,6 +1753,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
isDelivered:NO
|
||||
isRead:NO
|
||||
quotedMessage:nil
|
||||
contactShare:nil
|
||||
transaction:transaction];
|
||||
}];
|
||||
}
|
||||
@ -1788,6 +1801,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
isDelivered:isDelivered
|
||||
isRead:isRead
|
||||
quotedMessage:nil
|
||||
contactShare:nil
|
||||
transaction:transaction];
|
||||
}];
|
||||
}
|
||||
@ -1961,6 +1975,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
isDelivered:quotedMessageIsDelivered
|
||||
isRead:quotedMessageIsRead
|
||||
quotedMessage:nil
|
||||
contactShare:nil
|
||||
transaction:transaction];
|
||||
OWSAssert(messageToQuote);
|
||||
quotedMessage = [[OWSQuotedReplyModel quotedReplyForMessage:messageToQuote transaction:transaction]
|
||||
@ -1985,6 +2000,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
isDelivered:replyIsDelivered
|
||||
isRead:replyIsRead
|
||||
quotedMessage:quotedMessage
|
||||
contactShare:nil
|
||||
transaction:transaction];
|
||||
}
|
||||
}
|
||||
@ -2642,6 +2658,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
[actions addObjectsFromArray:[self allFakeSequenceActions:thread includeLabels:includeLabels]];
|
||||
[actions addObjectsFromArray:[self allFakeQuotedReplyActions:thread includeLabels:includeLabels]];
|
||||
[actions addObjectsFromArray:[self allFakeBackDatedActions:thread includeLabels:includeLabels]];
|
||||
[actions addObjectsFromArray:[self allShareContactActions:thread includeLabels:includeLabels]];
|
||||
return actions;
|
||||
}
|
||||
|
||||
@ -2832,6 +2849,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
isDelivered:NO
|
||||
isRead:NO
|
||||
quotedMessage:nil
|
||||
contactShare:nil
|
||||
transaction:transaction];
|
||||
[message setReceivedAtTimestamp:(uint64_t)((int64_t)[NSDate ows_millisecondTimeStamp] + dateOffset)];
|
||||
[message saveWithTransaction:transaction];
|
||||
@ -2882,6 +2900,70 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
#pragma mark -
|
||||
|
||||
typedef OWSContactShare * (^OWSContactShareBlock)(void);
|
||||
|
||||
+ (DebugUIMessagesAction *)fakeShareContactMessageAction:(TSThread *)thread
|
||||
label:(NSString *)label
|
||||
contactShareBlock:(OWSContactShareBlock)contactShareBlock
|
||||
{
|
||||
OWSAssert(thread);
|
||||
|
||||
return [DebugUIMessagesSingleAction
|
||||
actionWithLabel:[NSString stringWithFormat:@"Fake Contact Share (%@)", label]
|
||||
unstaggeredActionBlock:^(NSUInteger index, YapDatabaseReadWriteTransaction *transaction) {
|
||||
OWSContactShare *contactShare = contactShareBlock();
|
||||
TSOutgoingMessage *message = [self createFakeOutgoingMessage:thread
|
||||
messageBody:nil
|
||||
fakeAssetLoader:nil
|
||||
messageState:TSOutgoingMessageStateSent
|
||||
isDelivered:NO
|
||||
isRead:NO
|
||||
quotedMessage:nil
|
||||
contactShare:contactShare
|
||||
transaction:transaction];
|
||||
[message saveWithTransaction:transaction];
|
||||
}];
|
||||
}
|
||||
|
||||
+ (NSArray<DebugUIMessagesAction *> *)allShareContactActions:(TSThread *)thread includeLabels:(BOOL)includeLabels
|
||||
{
|
||||
OWSAssert(thread);
|
||||
|
||||
NSMutableArray<DebugUIMessagesAction *> *actions = [NSMutableArray new];
|
||||
|
||||
if (includeLabels) {
|
||||
[actions addObject:[self fakeOutgoingTextMessageAction:thread
|
||||
messageState:TSOutgoingMessageStateSent
|
||||
text:@"⚠️ Share Contact ⚠️"]];
|
||||
}
|
||||
|
||||
[actions addObject:[self fakeShareContactMessageAction:thread
|
||||
label:@"Name & Number"
|
||||
contactShareBlock:^{
|
||||
OWSContactShare *contactShare = [OWSContactShare new];
|
||||
contactShare.givenName = @"Alice";
|
||||
OWSContactSharePhoneNumber *phoneNumber = [OWSContactSharePhoneNumber new];
|
||||
phoneNumber.phoneType = OWSContactSharePhoneType_Home;
|
||||
phoneNumber.phoneNumber = @"+13213214321";
|
||||
contactShare.phoneNumbers = @[
|
||||
phoneNumber,
|
||||
];
|
||||
return contactShare;
|
||||
}]];
|
||||
|
||||
return actions;
|
||||
}
|
||||
|
||||
+ (DebugUIMessagesAction *)allShareContactAction:(TSThread *)thread
|
||||
{
|
||||
OWSAssert(thread);
|
||||
|
||||
return [DebugUIMessagesGroupAction allGroupActionWithLabel:@"All Fake Share Contact"
|
||||
subactions:[self allShareContactActions:thread includeLabels:YES]];
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
+ (NSString *)randomOversizeText
|
||||
{
|
||||
NSMutableString *message = [NSMutableString new];
|
||||
@ -3270,6 +3352,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
isDelivered:NO
|
||||
isRead:NO
|
||||
quotedMessage:nil
|
||||
contactShare:nil
|
||||
transaction:transaction];
|
||||
break;
|
||||
}
|
||||
@ -3323,6 +3406,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
isRead:NO
|
||||
isVoiceMessage:NO
|
||||
quotedMessage:nil
|
||||
contactShare:nil
|
||||
transaction:transaction];
|
||||
break;
|
||||
}
|
||||
@ -3943,6 +4027,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
isDelivered:(BOOL)isDelivered
|
||||
isRead:(BOOL)isRead
|
||||
quotedMessage:(nullable TSQuotedMessage *)quotedMessage
|
||||
contactShare:(nullable OWSContactShare *)contactShare
|
||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||
{
|
||||
OWSAssert(thread);
|
||||
@ -3968,6 +4053,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
isRead:isRead
|
||||
isVoiceMessage:attachment.isVoiceMessage
|
||||
quotedMessage:quotedMessage
|
||||
contactShare:contactShare
|
||||
transaction:transaction];
|
||||
}
|
||||
|
||||
@ -3980,6 +4066,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
isRead:(BOOL)isRead
|
||||
isVoiceMessage:(BOOL)isVoiceMessage
|
||||
quotedMessage:(nullable TSQuotedMessage *)quotedMessage
|
||||
contactShare:(nullable OWSContactShare *)contactShare
|
||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||
{
|
||||
OWSAssert(thread);
|
||||
@ -4001,7 +4088,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
isVoiceMessage:isVoiceMessage
|
||||
groupMetaMessage:TSGroupMessageUnspecified
|
||||
quotedMessage:quotedMessage
|
||||
contactShare:nil];
|
||||
contactShare:contactShare];
|
||||
|
||||
if (attachmentId.length > 0 && filename.length > 0) {
|
||||
message.attachmentFilenameMap[attachmentId] = filename;
|
||||
|
||||
@ -47,7 +47,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
_quotedMessage =
|
||||
[TSQuotedMessage quotedMessageForDataMessage:_dataMessage thread:_thread relay:relay transaction:transaction];
|
||||
_contactShare = [OWSContactShare contactShareMessageForDataMessage:_dataMessage transaction:transaction];
|
||||
_contactShare = [OWSContactShare contactShareForDataMessage:_dataMessage transaction:transaction];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
@ -0,0 +1,65 @@
|
||||
//
|
||||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSContactShare.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSContactSharePhoneNumber (Private)
|
||||
|
||||
@property (nonatomic) OWSContactSharePhoneType phoneType;
|
||||
@property (nonatomic, nullable) NSString *label;
|
||||
|
||||
@property (nonatomic) NSString *phoneNumber;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface OWSContactShareEmail (Private)
|
||||
|
||||
@property (nonatomic) OWSContactShareEmailType emailType;
|
||||
@property (nonatomic, nullable) NSString *label;
|
||||
|
||||
@property (nonatomic) NSString *email;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface OWSContactShareAddress (Private)
|
||||
|
||||
@property (nonatomic) OWSContactShareAddressType addressType;
|
||||
@property (nonatomic, nullable) NSString *label;
|
||||
|
||||
@property (nonatomic, nullable) NSString *street;
|
||||
@property (nonatomic, nullable) NSString *pobox;
|
||||
@property (nonatomic, nullable) NSString *neighborhood;
|
||||
@property (nonatomic, nullable) NSString *city;
|
||||
@property (nonatomic, nullable) NSString *region;
|
||||
@property (nonatomic, nullable) NSString *postcode;
|
||||
@property (nonatomic, nullable) NSString *country;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface OWSContactShare (Private)
|
||||
|
||||
@property (nonatomic, nullable) NSString *givenName;
|
||||
@property (nonatomic, nullable) NSString *familyName;
|
||||
@property (nonatomic, nullable) NSString *nameSuffix;
|
||||
@property (nonatomic, nullable) NSString *namePrefix;
|
||||
@property (nonatomic, nullable) NSString *middleName;
|
||||
|
||||
@property (nonatomic, nullable) NSArray<OWSContactSharePhoneNumber *> *phoneNumbers;
|
||||
@property (nonatomic, nullable) NSArray<OWSContactShareEmail *> *emails;
|
||||
@property (nonatomic, nullable) NSArray<OWSContactShareAddress *> *addresses;
|
||||
|
||||
@property (nonatomic, nullable) TSAttachment *avatar;
|
||||
@property (nonatomic) BOOL isProfileAvatar;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
@ -91,8 +91,8 @@ typedef NS_ENUM(NSUInteger, OWSContactShareAddressType) {
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
+ (OWSContactShare *_Nullable)contactShareMessageForDataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
|
||||
transaction:(YapDatabaseReadWriteTransaction *)transaction;
|
||||
+ (OWSContactShare *_Nullable)contactShareForDataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
|
||||
transaction:(YapDatabaseReadWriteTransaction *)transaction;
|
||||
|
||||
@end
|
||||
|
||||
|
||||
@ -3,63 +3,25 @@
|
||||
//
|
||||
|
||||
#import "OWSContactShare.h"
|
||||
#import "OWSContactShare+Private.h"
|
||||
#import "OWSSignalServiceProtos.pb.h"
|
||||
#import "TSAttachment.h"
|
||||
#import <YapDatabase/YapDatabaseTransaction.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSContactSharePhoneNumber ()
|
||||
|
||||
@property (nonatomic) OWSContactSharePhoneType phoneType;
|
||||
@property (nonatomic, nullable) NSString *label;
|
||||
|
||||
@property (nonatomic) NSString *phoneNumber;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation OWSContactSharePhoneNumber
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface OWSContactShareEmail ()
|
||||
|
||||
@property (nonatomic) OWSContactShareEmailType emailType;
|
||||
@property (nonatomic, nullable) NSString *label;
|
||||
|
||||
@property (nonatomic) NSString *email;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation OWSContactShareEmail
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface OWSContactShareAddress ()
|
||||
|
||||
@property (nonatomic) OWSContactShareAddressType addressType;
|
||||
@property (nonatomic, nullable) NSString *label;
|
||||
|
||||
@property (nonatomic, nullable) NSString *street;
|
||||
@property (nonatomic, nullable) NSString *pobox;
|
||||
@property (nonatomic, nullable) NSString *neighborhood;
|
||||
@property (nonatomic, nullable) NSString *city;
|
||||
@property (nonatomic, nullable) NSString *region;
|
||||
@property (nonatomic, nullable) NSString *postcode;
|
||||
@property (nonatomic, nullable) NSString *country;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation OWSContactShareAddress
|
||||
|
||||
@end
|
||||
@ -68,27 +30,14 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@interface OWSContactShare ()
|
||||
|
||||
@property (nonatomic, nullable) NSString *givenName;
|
||||
@property (nonatomic, nullable) NSString *familyName;
|
||||
@property (nonatomic, nullable) NSString *nameSuffix;
|
||||
@property (nonatomic, nullable) NSString *namePrefix;
|
||||
@property (nonatomic, nullable) NSString *middleName;
|
||||
|
||||
@property (nonatomic, nullable) NSArray<OWSContactSharePhoneNumber *> *phoneNumbers;
|
||||
@property (nonatomic, nullable) NSArray<OWSContactShareEmail *> *emails;
|
||||
@property (nonatomic, nullable) NSArray<OWSContactShareAddress *> *addresses;
|
||||
|
||||
@property (nonatomic, nullable) TSAttachment *avatar;
|
||||
@property (nonatomic) BOOL isProfileAvatar;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@implementation OWSContactShare
|
||||
|
||||
+ (OWSContactShare *_Nullable)contactShareMessageForDataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
|
||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||
+ (OWSContactShare *_Nullable)contactShareForDataMessage:(OWSSignalServiceProtosDataMessage *)dataMessage
|
||||
transaction:(YapDatabaseReadWriteTransaction *)transaction
|
||||
{
|
||||
OWSAssert(dataMessage);
|
||||
|
||||
|
||||
@ -33,7 +33,8 @@ typedef NS_ENUM(int32_t, TSErrorMessageType) {
|
||||
attachmentIds:(NSArray<NSString *> *)attachmentIds
|
||||
expiresInSeconds:(uint32_t)expiresInSeconds
|
||||
expireStartedAt:(uint64_t)expireStartedAt
|
||||
quotedMessage:(nullable TSQuotedMessage *)quotedMessage NS_UNAVAILABLE;
|
||||
quotedMessage:(nullable TSQuotedMessage *)quotedMessage
|
||||
contactShare:(nullable OWSContactShare *)contactShare NS_UNAVAILABLE;
|
||||
|
||||
- (instancetype)initWithCoder:(NSCoder *)coder NS_DESIGNATED_INITIALIZER;
|
||||
|
||||
|
||||
@ -18,7 +18,8 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
attachmentIds:(NSArray<NSString *> *)attachmentIds
|
||||
expiresInSeconds:(uint32_t)expiresInSeconds
|
||||
expireStartedAt:(uint64_t)expireStartedAt
|
||||
quotedMessage:(nullable TSQuotedMessage *)quotedMessage NS_UNAVAILABLE;
|
||||
quotedMessage:(nullable TSQuotedMessage *)quotedMessage
|
||||
contactShare:(nullable OWSContactShare *)contactShare NS_UNAVAILABLE;
|
||||
|
||||
/**
|
||||
* Inits an incoming group message that expires.
|
||||
|
||||
@ -74,7 +74,8 @@ typedef NS_ENUM(NSInteger, TSGroupMetaMessage) {
|
||||
attachmentIds:(NSArray<NSString *> *)attachmentIds
|
||||
expiresInSeconds:(uint32_t)expiresInSeconds
|
||||
expireStartedAt:(uint64_t)expireStartedAt
|
||||
quotedMessage:(nullable TSQuotedMessage *)quotedMessage NS_UNAVAILABLE;
|
||||
quotedMessage:(nullable TSQuotedMessage *)quotedMessage
|
||||
contactShare:(nullable OWSContactShare *)contactShare NS_UNAVAILABLE;
|
||||
|
||||
- (instancetype)initOutgoingMessageWithTimestamp:(uint64_t)timestamp
|
||||
inThread:(nullable TSThread *)thread
|
||||
|
||||
@ -998,7 +998,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
transaction:transaction];
|
||||
|
||||
OWSContactShare *_Nullable contactShare =
|
||||
[OWSContactShare contactShareMessageForDataMessage:dataMessage transaction:transaction];
|
||||
[OWSContactShare contactShareForDataMessage:dataMessage transaction:transaction];
|
||||
|
||||
DDLogDebug(@"%@ incoming message from: %@ for group: %@ with timestamp: %lu",
|
||||
self.logTag,
|
||||
@ -1050,7 +1050,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||
relay:envelope.relay
|
||||
transaction:transaction];
|
||||
OWSContactShare *_Nullable contactShare =
|
||||
[OWSContactShare contactShareMessageForDataMessage:dataMessage transaction:transaction];
|
||||
[OWSContactShare contactShareForDataMessage:dataMessage transaction:transaction];
|
||||
|
||||
TSIncomingMessage *incomingMessage =
|
||||
[[TSIncomingMessage alloc] initIncomingMessageWithTimestamp:timestamp
|
||||
|
||||
Loading…
Reference in New Issue
Block a user