#import "TGBridgeMessage.h" #import "TGPeerIdAdapter.h" NSString *const TGBridgeMessageIdentifierKey = @"identifier"; NSString *const TGBridgeMessageDateKey = @"date"; NSString *const TGBridgeMessageRandomIdKey = @"randomId"; NSString *const TGBridgeMessageFromUidKey = @"fromUid"; NSString *const TGBridgeMessageCidKey = @"cid"; NSString *const TGBridgeMessageTextKey = @"text"; NSString *const TGBridgeMessageUnreadKey = @"unread"; NSString *const TGBridgeMessageOutgoingKey = @"outgoing"; NSString *const TGBridgeMessageMediaKey = @"media"; NSString *const TGBridgeMessageDeliveryStateKey = @"deliveryState"; NSString *const TGBridgeMessageForceReplyKey = @"forceReply"; NSString *const TGBridgeMessageKey = @"message"; NSString *const TGBridgeMessagesArrayKey = @"messages"; @interface TGBridgeMessage () { NSArray *_textCheckingResults; } @end @implementation TGBridgeMessage - (instancetype)initWithCoder:(NSCoder *)aDecoder { self = [super init]; if (self != nil) { _identifier = [aDecoder decodeInt32ForKey:TGBridgeMessageIdentifierKey]; _date = [aDecoder decodeDoubleForKey:TGBridgeMessageDateKey]; _randomId = [aDecoder decodeInt64ForKey:TGBridgeMessageRandomIdKey]; _fromUid = [aDecoder decodeInt64ForKey:TGBridgeMessageFromUidKey]; _cid = [aDecoder decodeInt64ForKey:TGBridgeMessageCidKey]; _text = [aDecoder decodeObjectForKey:TGBridgeMessageTextKey]; _outgoing = [aDecoder decodeBoolForKey:TGBridgeMessageOutgoingKey]; _unread = [aDecoder decodeBoolForKey:TGBridgeMessageUnreadKey]; _deliveryState = [aDecoder decodeInt32ForKey:TGBridgeMessageDeliveryStateKey]; _media = [aDecoder decodeObjectForKey:TGBridgeMessageMediaKey]; _forceReply = [aDecoder decodeBoolForKey:TGBridgeMessageForceReplyKey]; } return self; } - (void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeInt32:self.identifier forKey:TGBridgeMessageIdentifierKey]; [aCoder encodeDouble:self.date forKey:TGBridgeMessageDateKey]; [aCoder encodeInt64:self.randomId forKey:TGBridgeMessageRandomIdKey]; [aCoder encodeInt64:self.fromUid forKey:TGBridgeMessageFromUidKey]; [aCoder encodeInt64:self.cid forKey:TGBridgeMessageCidKey]; [aCoder encodeObject:self.text forKey:TGBridgeMessageTextKey]; [aCoder encodeBool:self.outgoing forKey:TGBridgeMessageOutgoingKey]; [aCoder encodeBool:self.unread forKey:TGBridgeMessageUnreadKey]; [aCoder encodeInt32:self.deliveryState forKey:TGBridgeMessageDeliveryStateKey]; [aCoder encodeObject:self.media forKey:TGBridgeMessageMediaKey]; [aCoder encodeBool:self.forceReply forKey:TGBridgeMessageForceReplyKey]; } - (NSIndexSet *)involvedUserIds { NSMutableIndexSet *userIds = [[NSMutableIndexSet alloc] init]; if (!TGPeerIdIsChannel(self.fromUid)) [userIds addIndex:(int32_t)self.fromUid]; for (TGBridgeMediaAttachment *attachment in self.media) { if ([attachment isKindOfClass:[TGBridgeContactMediaAttachment class]]) { TGBridgeContactMediaAttachment *contactAttachment = (TGBridgeContactMediaAttachment *)attachment; if (contactAttachment.uid != 0) [userIds addIndex:contactAttachment.uid]; } else if ([attachment isKindOfClass:[TGBridgeForwardedMessageMediaAttachment class]]) { TGBridgeForwardedMessageMediaAttachment *forwardAttachment = (TGBridgeForwardedMessageMediaAttachment *)attachment; if (forwardAttachment.peerId != 0 && !TGPeerIdIsChannel(forwardAttachment.peerId)) [userIds addIndex:(int32_t)forwardAttachment.peerId]; } else if ([attachment isKindOfClass:[TGBridgeReplyMessageMediaAttachment class]]) { TGBridgeReplyMessageMediaAttachment *replyAttachment = (TGBridgeReplyMessageMediaAttachment *)attachment; if (replyAttachment.message != nil && !TGPeerIdIsChannel(replyAttachment.message.fromUid)) [userIds addIndex:(int32_t)replyAttachment.message.fromUid]; } else if ([attachment isKindOfClass:[TGBridgeActionMediaAttachment class]]) { TGBridgeActionMediaAttachment *actionAttachment = (TGBridgeActionMediaAttachment *)attachment; if (actionAttachment.actionData[@"uid"] != nil) [userIds addIndex:[actionAttachment.actionData[@"uid"] int32Value]]; } } return userIds; } - (NSArray *)textCheckingResults { if (_textCheckingResults == nil) { NSMutableArray *results = [[NSMutableArray alloc] init]; NSArray *entities = nil; for (TGBridgeMediaAttachment *attachment in self.media) { if ([attachment isKindOfClass:[TGBridgeMessageEntitiesAttachment class]]) { entities = ((TGBridgeMessageEntitiesAttachment *)attachment).entities; break; } } for (TGBridgeMessageEntity *entity in entities) { TGBridgeTextCheckingResult *result = [[TGBridgeTextCheckingResult alloc] init]; result.range = entity.range; if ([entity isKindOfClass:[TGBridgeMessageEntityBold class]]) result.type = TGBridgeTextCheckingResultTypeBold; else if ([entity isKindOfClass:[TGBridgeMessageEntityItalic class]]) result.type = TGBridgeTextCheckingResultTypeItalic; else if ([entity isKindOfClass:[TGBridgeMessageEntityCode class]]) result.type = TGBridgeTextCheckingResultTypeCode; else if ([entity isKindOfClass:[TGBridgeMessageEntityPre class]]) result.type = TGBridgeTextCheckingResultTypePre; if (result.type != TGBridgeTextCheckingResultTypeUndefined) [results addObject:result]; } _textCheckingResults = results; } return _textCheckingResults; } - (BOOL)isEqual:(id)object { if (object == self) return YES; if (!object || ![object isKindOfClass:[self class]]) return NO; TGBridgeMessage *message = (TGBridgeMessage *)object; if (self.randomId != 0) return self.randomId == message.randomId; else return self.identifier == message.identifier; } + (instancetype)temporaryNewMessageForText:(NSString *)text userId:(int32_t)userId { return [self temporaryNewMessageForText:text userId:userId replyToMessage:nil]; } + (instancetype)temporaryNewMessageForText:(NSString *)text userId:(int32_t)userId replyToMessage:(TGBridgeMessage *)replyToMessage { int64_t randomId = 0; arc4random_buf(&randomId, 8); int32_t messageId = 0; arc4random_buf(&messageId, 4); TGBridgeMessage *message = [[TGBridgeMessage alloc] init]; message->_identifier = -abs(messageId); message->_fromUid = userId; message->_randomId = randomId; message->_unread = true; message->_outgoing = true; message->_deliveryState = TGBridgeMessageDeliveryStatePending; message->_text = text; message->_date = [[NSDate date] timeIntervalSince1970]; if (replyToMessage != nil) { TGBridgeReplyMessageMediaAttachment *replyAttachment = [[TGBridgeReplyMessageMediaAttachment alloc] init]; replyAttachment.mid = replyToMessage.identifier; replyAttachment.message = replyToMessage; message->_media = @[ replyToMessage ]; } return message; } + (instancetype)temporaryNewMessageForSticker:(TGBridgeDocumentMediaAttachment *)sticker userId:(int32_t)userId { return [self _temporaryNewMessageForMediaAttachment:sticker userId:userId]; } + (instancetype)temporaryNewMessageForLocation:(TGBridgeLocationMediaAttachment *)location userId:(int32_t)userId { return [self _temporaryNewMessageForMediaAttachment:location userId:userId]; } + (instancetype)temporaryNewMessageForAudioWithDuration:(int32_t)duration userId:(int32_t)userId localAudioId:(int64_t)localAudioId { TGBridgeDocumentMediaAttachment *document = [[TGBridgeDocumentMediaAttachment alloc] init]; document.isAudio = true; document.isVoice = true; document.localDocumentId = localAudioId; document.duration = duration; return [self _temporaryNewMessageForMediaAttachment:document userId:userId]; } + (instancetype)_temporaryNewMessageForMediaAttachment:(TGBridgeMediaAttachment *)attachment userId:(int32_t)userId { int64_t randomId = 0; arc4random_buf(&randomId, 8); int32_t messageId = 0; arc4random_buf(&messageId, 4); TGBridgeMessage *message = [[TGBridgeMessage alloc] init]; message->_identifier = -abs(messageId); message->_fromUid = userId; message->_unread = true; message->_outgoing = true; message->_deliveryState = TGBridgeMessageDeliveryStatePending; message->_date = [[NSDate date] timeIntervalSince1970]; message->_media = @[ attachment ]; return message; } @end @implementation TGBridgeTextCheckingResult @end