session-ios/Signal/src/Models/TSMessageAdapaters/TSMessageAdapter.m

422 lines
16 KiB
Mathematica
Raw Normal View History

//
2017-02-16 23:59:40 +01:00
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
2014-11-25 16:38:33 +01:00
//
2017-05-16 17:26:01 +02:00
#import "TSMessageAdapter.h"
2017-02-16 23:59:40 +01:00
#import "AttachmentSharing.h"
#import "OWSCall.h"
#import "OWSContactOffersInteraction.h"
#import "Signal-Swift.h"
#import "TSAttachmentPointer.h"
#import "TSAttachmentStream.h"
2014-11-25 16:38:33 +01:00
#import "TSCall.h"
#import "TSContactThread.h"
#import "TSContentAdapters.h"
2014-11-25 16:38:33 +01:00
#import "TSErrorMessage.h"
#import "TSGenericAttachmentAdapter.h"
#import "TSGroupThread.h"
#import "TSIncomingMessage.h"
#import "TSInfoMessage.h"
#import "TSOutgoingMessage.h"
2017-05-16 17:26:01 +02:00
#import "TSUnreadIndicatorInteraction.h"
#import <MobileCoreServices/MobileCoreServices.h>
2017-03-29 20:49:26 +02:00
NS_ASSUME_NONNULL_BEGIN
2014-11-25 16:38:33 +01:00
@interface TSMessageAdapter ()
// ---
@property (nonatomic, retain) TSContactThread *thread;
// OR for groups
@property (nonatomic, copy) NSString *senderId;
@property (nonatomic, copy) NSString *senderDisplayName;
2014-11-25 16:38:33 +01:00
// for InfoMessages
@property TSInfoMessageType infoMessageType;
// for ErrorMessages
2016-11-10 16:15:08 +01:00
@property TSErrorMessageType errorMessageType;
// for outgoing Messages only
@property NSInteger outgoingMessageStatus;
2014-12-18 00:00:10 +01:00
// for MediaMessages
@property JSQMediaItem<OWSMessageEditing> *mediaItem;
2014-12-18 00:00:10 +01:00
Disappearing Messages * Per thread settings menu accessed by tapping on thread title This removed the toggle-phone behavior. You'll be able to see the phone number in the settings table view. This removed the "add contact" functionality, although it was already broken for ios>=9 (which is basically everybody). The group actions menu was absorbed into this screen * Added a confirm alert to leave group (fixes #938) * New Translation Strings * Extend "Add People" label to fit translations. * resolved issues with translations not fitting in group menu * Fix the long standing type warning where TSCalls were assigned to a TSMessageAdapter. * Can delete info messages Follow the JSQMVC pattern and put UIResponder-able content in the messageBubbleContainer. This gives us more functionality *and* allows us to delete some code. yay! It's still not yet possible to delete phone messages. =( * Fixed some compiler warnings. * xcode8 touching storyboard. So long xcode7! * Fixup multiline info messages. We were seeing info messages like "You set disappearing message timer to 10" instead of "You set disappearing message timer to 10 seconds." Admittedly this isn't a very good fix, as now one liners feel like they have too much padding. If the message is well over one line, we were wrapping properly, but there's a problem when the message is *just barely* two lines, the cell height grows, but the label still thinks it's just one line (as evinced by the one line appearing in the center of the label frame. The result being that the last word of the label is cropped. * Disable group actions after leaving group. // FREEBIE
2016-09-21 14:37:51 +02:00
// -- Redeclaring properties from OWSMessageData protocol to synthesize variables
@property (nonatomic) TSMessageAdapterType messageType;
@property (nonatomic) BOOL isExpiringMessage;
@property (nonatomic) BOOL shouldStartExpireTimer;
@property (nonatomic) double expiresAtSeconds;
Disappearing Messages * Per thread settings menu accessed by tapping on thread title This removed the toggle-phone behavior. You'll be able to see the phone number in the settings table view. This removed the "add contact" functionality, although it was already broken for ios>=9 (which is basically everybody). The group actions menu was absorbed into this screen * Added a confirm alert to leave group (fixes #938) * New Translation Strings * Extend "Add People" label to fit translations. * resolved issues with translations not fitting in group menu * Fix the long standing type warning where TSCalls were assigned to a TSMessageAdapter. * Can delete info messages Follow the JSQMVC pattern and put UIResponder-able content in the messageBubbleContainer. This gives us more functionality *and* allows us to delete some code. yay! It's still not yet possible to delete phone messages. =( * Fixed some compiler warnings. * xcode8 touching storyboard. So long xcode7! * Fixup multiline info messages. We were seeing info messages like "You set disappearing message timer to 10" instead of "You set disappearing message timer to 10 seconds." Admittedly this isn't a very good fix, as now one liners feel like they have too much padding. If the message is well over one line, we were wrapping properly, but there's a problem when the message is *just barely* two lines, the cell height grows, but the label still thinks it's just one line (as evinced by the one line appearing in the center of the label frame. The result being that the last word of the label is cropped. * Disable group actions after leaving group. // FREEBIE
2016-09-21 14:37:51 +02:00
@property (nonatomic) uint32_t expiresInSeconds;
2014-11-25 16:38:33 +01:00
@property (nonatomic) NSString *messageBody;
2014-11-25 16:38:33 +01:00
@property (nonatomic) NSString *interactionUniqueId;
2014-11-27 03:10:00 +01:00
2014-11-25 16:38:33 +01:00
@end
2017-03-29 20:49:26 +02:00
#pragma mark -
2014-11-25 16:38:33 +01:00
@implementation TSMessageAdapter
Disappearing Messages * Per thread settings menu accessed by tapping on thread title This removed the toggle-phone behavior. You'll be able to see the phone number in the settings table view. This removed the "add contact" functionality, although it was already broken for ios>=9 (which is basically everybody). The group actions menu was absorbed into this screen * Added a confirm alert to leave group (fixes #938) * New Translation Strings * Extend "Add People" label to fit translations. * resolved issues with translations not fitting in group menu * Fix the long standing type warning where TSCalls were assigned to a TSMessageAdapter. * Can delete info messages Follow the JSQMVC pattern and put UIResponder-able content in the messageBubbleContainer. This gives us more functionality *and* allows us to delete some code. yay! It's still not yet possible to delete phone messages. =( * Fixed some compiler warnings. * xcode8 touching storyboard. So long xcode7! * Fixup multiline info messages. We were seeing info messages like "You set disappearing message timer to 10" instead of "You set disappearing message timer to 10 seconds." Admittedly this isn't a very good fix, as now one liners feel like they have too much padding. If the message is well over one line, we were wrapping properly, but there's a problem when the message is *just barely* two lines, the cell height grows, but the label still thinks it's just one line (as evinced by the one line appearing in the center of the label frame. The result being that the last word of the label is cropped. * Disable group actions after leaving group. // FREEBIE
2016-09-21 14:37:51 +02:00
- (instancetype)initWithInteraction:(TSInteraction *)interaction
{
Disappearing Messages * Per thread settings menu accessed by tapping on thread title This removed the toggle-phone behavior. You'll be able to see the phone number in the settings table view. This removed the "add contact" functionality, although it was already broken for ios>=9 (which is basically everybody). The group actions menu was absorbed into this screen * Added a confirm alert to leave group (fixes #938) * New Translation Strings * Extend "Add People" label to fit translations. * resolved issues with translations not fitting in group menu * Fix the long standing type warning where TSCalls were assigned to a TSMessageAdapter. * Can delete info messages Follow the JSQMVC pattern and put UIResponder-able content in the messageBubbleContainer. This gives us more functionality *and* allows us to delete some code. yay! It's still not yet possible to delete phone messages. =( * Fixed some compiler warnings. * xcode8 touching storyboard. So long xcode7! * Fixup multiline info messages. We were seeing info messages like "You set disappearing message timer to 10" instead of "You set disappearing message timer to 10 seconds." Admittedly this isn't a very good fix, as now one liners feel like they have too much padding. If the message is well over one line, we were wrapping properly, but there's a problem when the message is *just barely* two lines, the cell height grows, but the label still thinks it's just one line (as evinced by the one line appearing in the center of the label frame. The result being that the last word of the label is cropped. * Disable group actions after leaving group. // FREEBIE
2016-09-21 14:37:51 +02:00
self = [super init];
if (!self) {
return self;
}
_interaction = interaction;
self.interactionUniqueId = interaction.uniqueId;
Disappearing Messages * Per thread settings menu accessed by tapping on thread title This removed the toggle-phone behavior. You'll be able to see the phone number in the settings table view. This removed the "add contact" functionality, although it was already broken for ios>=9 (which is basically everybody). The group actions menu was absorbed into this screen * Added a confirm alert to leave group (fixes #938) * New Translation Strings * Extend "Add People" label to fit translations. * resolved issues with translations not fitting in group menu * Fix the long standing type warning where TSCalls were assigned to a TSMessageAdapter. * Can delete info messages Follow the JSQMVC pattern and put UIResponder-able content in the messageBubbleContainer. This gives us more functionality *and* allows us to delete some code. yay! It's still not yet possible to delete phone messages. =( * Fixed some compiler warnings. * xcode8 touching storyboard. So long xcode7! * Fixup multiline info messages. We were seeing info messages like "You set disappearing message timer to 10" instead of "You set disappearing message timer to 10 seconds." Admittedly this isn't a very good fix, as now one liners feel like they have too much padding. If the message is well over one line, we were wrapping properly, but there's a problem when the message is *just barely* two lines, the cell height grows, but the label still thinks it's just one line (as evinced by the one line appearing in the center of the label frame. The result being that the last word of the label is cropped. * Disable group actions after leaving group. // FREEBIE
2016-09-21 14:37:51 +02:00
if ([interaction isKindOfClass:[TSMessage class]]) {
TSMessage *message = (TSMessage *)interaction;
_isExpiringMessage = message.isExpiringMessage;
_expiresAtSeconds = message.expiresAt / 1000.0;
Disappearing Messages * Per thread settings menu accessed by tapping on thread title This removed the toggle-phone behavior. You'll be able to see the phone number in the settings table view. This removed the "add contact" functionality, although it was already broken for ios>=9 (which is basically everybody). The group actions menu was absorbed into this screen * Added a confirm alert to leave group (fixes #938) * New Translation Strings * Extend "Add People" label to fit translations. * resolved issues with translations not fitting in group menu * Fix the long standing type warning where TSCalls were assigned to a TSMessageAdapter. * Can delete info messages Follow the JSQMVC pattern and put UIResponder-able content in the messageBubbleContainer. This gives us more functionality *and* allows us to delete some code. yay! It's still not yet possible to delete phone messages. =( * Fixed some compiler warnings. * xcode8 touching storyboard. So long xcode7! * Fixup multiline info messages. We were seeing info messages like "You set disappearing message timer to 10" instead of "You set disappearing message timer to 10 seconds." Admittedly this isn't a very good fix, as now one liners feel like they have too much padding. If the message is well over one line, we were wrapping properly, but there's a problem when the message is *just barely* two lines, the cell height grows, but the label still thinks it's just one line (as evinced by the one line appearing in the center of the label frame. The result being that the last word of the label is cropped. * Disable group actions after leaving group. // FREEBIE
2016-09-21 14:37:51 +02:00
_expiresInSeconds = message.expiresInSeconds;
_shouldStartExpireTimer = message.shouldStartExpireTimer;
Disappearing Messages * Per thread settings menu accessed by tapping on thread title This removed the toggle-phone behavior. You'll be able to see the phone number in the settings table view. This removed the "add contact" functionality, although it was already broken for ios>=9 (which is basically everybody). The group actions menu was absorbed into this screen * Added a confirm alert to leave group (fixes #938) * New Translation Strings * Extend "Add People" label to fit translations. * resolved issues with translations not fitting in group menu * Fix the long standing type warning where TSCalls were assigned to a TSMessageAdapter. * Can delete info messages Follow the JSQMVC pattern and put UIResponder-able content in the messageBubbleContainer. This gives us more functionality *and* allows us to delete some code. yay! It's still not yet possible to delete phone messages. =( * Fixed some compiler warnings. * xcode8 touching storyboard. So long xcode7! * Fixup multiline info messages. We were seeing info messages like "You set disappearing message timer to 10" instead of "You set disappearing message timer to 10 seconds." Admittedly this isn't a very good fix, as now one liners feel like they have too much padding. If the message is well over one line, we were wrapping properly, but there's a problem when the message is *just barely* two lines, the cell height grows, but the label still thinks it's just one line (as evinced by the one line appearing in the center of the label frame. The result being that the last word of the label is cropped. * Disable group actions after leaving group. // FREEBIE
2016-09-21 14:37:51 +02:00
} else {
_isExpiringMessage = NO;
Disappearing Messages * Per thread settings menu accessed by tapping on thread title This removed the toggle-phone behavior. You'll be able to see the phone number in the settings table view. This removed the "add contact" functionality, although it was already broken for ios>=9 (which is basically everybody). The group actions menu was absorbed into this screen * Added a confirm alert to leave group (fixes #938) * New Translation Strings * Extend "Add People" label to fit translations. * resolved issues with translations not fitting in group menu * Fix the long standing type warning where TSCalls were assigned to a TSMessageAdapter. * Can delete info messages Follow the JSQMVC pattern and put UIResponder-able content in the messageBubbleContainer. This gives us more functionality *and* allows us to delete some code. yay! It's still not yet possible to delete phone messages. =( * Fixed some compiler warnings. * xcode8 touching storyboard. So long xcode7! * Fixup multiline info messages. We were seeing info messages like "You set disappearing message timer to 10" instead of "You set disappearing message timer to 10 seconds." Admittedly this isn't a very good fix, as now one liners feel like they have too much padding. If the message is well over one line, we were wrapping properly, but there's a problem when the message is *just barely* two lines, the cell height grows, but the label still thinks it's just one line (as evinced by the one line appearing in the center of the label frame. The result being that the last word of the label is cropped. * Disable group actions after leaving group. // FREEBIE
2016-09-21 14:37:51 +02:00
}
return self;
}
+ (NSCache *)displayableTextCache
{
static NSCache *cache = nil;
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
cache = [NSCache new];
// Cache the results for up to 1,000 messages.
cache.countLimit = 1000;
});
return cache;
}
+ (id<OWSMessageData>)messageViewDataWithInteraction:(TSInteraction *)interaction inThread:(TSThread *)thread contactsManager:(id<ContactsManagerProtocol>)contactsManager
Disappearing Messages * Per thread settings menu accessed by tapping on thread title This removed the toggle-phone behavior. You'll be able to see the phone number in the settings table view. This removed the "add contact" functionality, although it was already broken for ios>=9 (which is basically everybody). The group actions menu was absorbed into this screen * Added a confirm alert to leave group (fixes #938) * New Translation Strings * Extend "Add People" label to fit translations. * resolved issues with translations not fitting in group menu * Fix the long standing type warning where TSCalls were assigned to a TSMessageAdapter. * Can delete info messages Follow the JSQMVC pattern and put UIResponder-able content in the messageBubbleContainer. This gives us more functionality *and* allows us to delete some code. yay! It's still not yet possible to delete phone messages. =( * Fixed some compiler warnings. * xcode8 touching storyboard. So long xcode7! * Fixup multiline info messages. We were seeing info messages like "You set disappearing message timer to 10" instead of "You set disappearing message timer to 10 seconds." Admittedly this isn't a very good fix, as now one liners feel like they have too much padding. If the message is well over one line, we were wrapping properly, but there's a problem when the message is *just barely* two lines, the cell height grows, but the label still thinks it's just one line (as evinced by the one line appearing in the center of the label frame. The result being that the last word of the label is cropped. * Disable group actions after leaving group. // FREEBIE
2016-09-21 14:37:51 +02:00
{
TSMessageAdapter *adapter = [[TSMessageAdapter alloc] initWithInteraction:interaction];
2014-11-25 16:38:33 +01:00
if ([thread isKindOfClass:[TSContactThread class]]) {
adapter.thread = (TSContactThread *)thread;
2014-11-25 19:06:09 +01:00
if ([interaction isKindOfClass:[TSIncomingMessage class]]) {
NSString *contactId = ((TSContactThread *)thread).contactIdentifier;
2014-11-25 19:06:09 +01:00
adapter.senderId = contactId;
adapter.senderDisplayName = [contactsManager displayNameForPhoneIdentifier:contactId];
adapter.messageType = TSIncomingMessageAdapter;
} else {
adapter.senderId = ME_MESSAGE_IDENTIFIER;
adapter.senderDisplayName = NSLocalizedString(@"ME_STRING", @"");
adapter.messageType = TSOutgoingMessageAdapter;
2014-11-25 19:06:09 +01:00
}
} else if ([thread isKindOfClass:[TSGroupThread class]]) {
2014-11-25 16:38:33 +01:00
if ([interaction isKindOfClass:[TSIncomingMessage class]]) {
TSIncomingMessage *message = (TSIncomingMessage *)interaction;
adapter.senderId = message.authorId;
adapter.senderDisplayName = [contactsManager displayNameForPhoneIdentifier:message.authorId];
adapter.messageType = TSIncomingMessageAdapter;
} else {
adapter.senderId = ME_MESSAGE_IDENTIFIER;
adapter.senderDisplayName = NSLocalizedString(@"ME_STRING", @"");
adapter.messageType = TSOutgoingMessageAdapter;
2014-11-25 16:38:33 +01:00
}
2017-05-16 17:26:01 +02:00
} else {
OWSFail(@"%@ Unknown thread type: %@", self.tag, [thread class]);
2014-11-25 16:38:33 +01:00
}
if ([interaction isKindOfClass:[TSIncomingMessage class]] ||
[interaction isKindOfClass:[TSOutgoingMessage class]]) {
TSMessage *message = (TSMessage *)interaction;
adapter.messageBody = [[DisplayableTextFilter new] displayableText:message.body];
if ([message hasAttachments]) {
for (NSString *attachmentID in message.attachmentIds) {
2014-12-21 12:52:42 +01:00
TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:attachmentID];
BOOL isIncomingAttachment = [interaction isKindOfClass:[TSIncomingMessage class]];
2014-12-21 12:52:42 +01:00
if ([attachment isKindOfClass:[TSAttachmentStream class]]) {
TSAttachmentStream *stream = (TSAttachmentStream *)attachment;
if ([attachment.contentType isEqualToString:OWSMimeTypeOversizeTextMessage]) {
NSString *displayableText = [[self displayableTextCache] objectForKey:interaction.uniqueId];
if (!displayableText) {
NSData *textData = [NSData dataWithContentsOfURL:stream.mediaURL];
NSString *fullText = [[NSString alloc] initWithData:textData encoding:NSUTF8StringEncoding];
// Only show up to 2kb of text.
const NSUInteger kMaxTextDisplayLength = 2 * 1024;
displayableText = [[DisplayableTextFilter new] displayableText:fullText];
if (displayableText.length > kMaxTextDisplayLength) {
// Trim whitespace before _AND_ after slicing the snipper from the string.
NSString *snippet = [[[displayableText
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]
substringWithRange:NSMakeRange(0, kMaxTextDisplayLength)]
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
displayableText =
[NSString stringWithFormat:NSLocalizedString(@"OVERSIZE_TEXT_DISPLAY_FORMAT",
@"A display format for oversize text messages."),
snippet];
}
if (!displayableText) {
displayableText = @"";
}
[[self displayableTextCache] setObject:displayableText forKey:interaction.uniqueId];
}
adapter.messageBody = displayableText;
} else if ([stream isAnimated]) {
adapter.mediaItem =
[[TSAnimatedAdapter alloc] initWithAttachment:stream incoming:isIncomingAttachment];
2017-03-29 20:49:26 +02:00
adapter.mediaItem.appliesMediaViewMaskAsOutgoing = !isIncomingAttachment;
break;
} else if ([stream isImage]) {
adapter.mediaItem =
[[TSPhotoAdapter alloc] initWithAttachment:stream incoming:isIncomingAttachment];
2017-03-29 20:49:26 +02:00
adapter.mediaItem.appliesMediaViewMaskAsOutgoing = !isIncomingAttachment;
break;
2017-04-11 15:16:10 +02:00
} else if ([stream isVideo] || [stream isAudio]) {
adapter.mediaItem = [[TSVideoAttachmentAdapter alloc]
initWithAttachment:stream
incoming:[interaction isKindOfClass:[TSIncomingMessage class]]];
2017-03-29 20:49:26 +02:00
adapter.mediaItem.appliesMediaViewMaskAsOutgoing = !isIncomingAttachment;
break;
} else {
adapter.mediaItem = [[TSGenericAttachmentAdapter alloc]
initWithAttachment:stream
incoming:[interaction isKindOfClass:[TSIncomingMessage class]]];
2017-03-29 20:49:26 +02:00
adapter.mediaItem.appliesMediaViewMaskAsOutgoing = !isIncomingAttachment;
break;
}
} else if ([attachment isKindOfClass:[TSAttachmentPointer class]]) {
TSAttachmentPointer *pointer = (TSAttachmentPointer *)attachment;
adapter.mediaItem =
[[AttachmentPointerAdapter alloc] initWithAttachmentPointer:pointer
isIncoming:isIncomingAttachment];
} else {
DDLogError(@"We retrieved an attachment that doesn't have a known type : %@",
NSStringFromClass([attachment class]));
2014-12-18 00:00:10 +01:00
}
}
} else {
NSString *displayableText = [[self displayableTextCache] objectForKey:interaction.uniqueId];
if (!displayableText) {
displayableText = [[DisplayableTextFilter new] displayableText:message.body];
if (!displayableText) {
displayableText = @"";
}
[[self displayableTextCache] setObject:displayableText forKey:interaction.uniqueId];
}
adapter.messageBody = displayableText;
2014-12-18 00:00:10 +01:00
}
} else if ([interaction isKindOfClass:[TSCall class]]) {
TSCall *callRecord = (TSCall *)interaction;
return [[OWSCall alloc] initWithCallRecord:callRecord];
} else if ([interaction isKindOfClass:[TSInfoMessage class]]) {
TSInfoMessage *infoMessage = (TSInfoMessage *)interaction;
adapter.infoMessageType = infoMessage.messageType;
adapter.messageBody = infoMessage.description;
adapter.messageType = TSInfoMessageAdapter;
2017-05-16 17:26:01 +02:00
} else if ([interaction isKindOfClass:[TSUnreadIndicatorInteraction class]]) {
adapter.messageType = TSUnreadIndicatorAdapter;
} else if ([interaction isKindOfClass:[OWSContactOffersInteraction class]]) {
adapter.messageType = OWSContactOffersAdapter;
2017-05-16 17:26:01 +02:00
} else if ([interaction isKindOfClass:[TSErrorMessage class]]) {
TSErrorMessage *errorMessage = (TSErrorMessage *)interaction;
2016-11-10 16:15:08 +01:00
adapter.errorMessageType = errorMessage.errorType;
adapter.messageBody = errorMessage.description;
adapter.messageType = TSErrorMessageAdapter;
2017-05-16 17:26:01 +02:00
} else {
OWSFail(@"%@ Unknown interaction type: %@", self.tag, [interaction class]);
2014-11-25 16:38:33 +01:00
}
if ([interaction isKindOfClass:[TSOutgoingMessage class]]) {
adapter.outgoingMessageStatus = ((TSOutgoingMessage *)interaction).messageState;
}
OWSAssert(adapter.date);
2014-11-25 16:38:33 +01:00
return adapter;
}
- (NSString *)senderId {
2014-11-25 19:06:09 +01:00
if (_senderId) {
return _senderId;
} else {
2014-11-25 19:06:09 +01:00
return ME_MESSAGE_IDENTIFIER;
}
2014-11-25 16:38:33 +01:00
}
- (NSDate *)date {
return self.interaction.dateForSorting;
2014-11-25 16:38:33 +01:00
}
#pragma mark - OWSMessageEditing Protocol
+ (SEL)messageMetadataSelector
{
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wundeclared-selector"
return @selector(showMessageMetadata:);
#pragma clang diagnostic pop
}
- (BOOL)canPerformEditingAction:(SEL)action
{
if ([self attachmentStream] && ![self attachmentStream].isUploaded) {
return NO;
}
// Deletes are always handled by TSMessageAdapter
if (action == @selector(delete:)) {
return YES;
} else if (action == [TSMessageAdapter messageMetadataSelector]) {
return ([self.interaction isKindOfClass:[TSIncomingMessage class]] ||
[self.interaction isKindOfClass:[TSOutgoingMessage class]]);
}
// Delegate other actions for media items
2017-02-16 23:59:40 +01:00
if ([self attachmentStream] && action == NSSelectorFromString(@"share:")) {
return YES;
} else if (self.isMediaMessage) {
return [self.mediaItem canPerformEditingAction:action];
} else if (self.messageType == TSInfoMessageAdapter || self.messageType == TSErrorMessageAdapter) {
return NO;
} else {
// Text message - no media attachment
if (action == @selector(copy:)) {
return YES;
}
}
return NO;
}
- (void)performEditingAction:(SEL)action
{
// Deletes are always handled by TSMessageAdapter
if (action == @selector(delete:)) {
DDLogDebug(@"Deleting interaction with uniqueId: %@", self.interaction.uniqueId);
[self.interaction remove];
return;
2017-02-16 23:59:40 +01:00
} else if (action == NSSelectorFromString(@"share:")) {
TSAttachmentStream *stream = [self attachmentStream];
OWSAssert(stream);
if (stream) {
[AttachmentSharing showShareUIForAttachment:stream];
}
return;
} else if (action == [TSMessageAdapter messageMetadataSelector]) {
OWSFail(@"Conversation view should handle message metadata events.");
return;
}
// Delegate other actions for media items
if (self.isMediaMessage) {
[self.mediaItem performEditingAction:action];
return;
} else {
// Text message - no media attachment
if (action == @selector(copy:)) {
UIPasteboard.generalPasteboard.string = self.messageBody;
return;
}
}
// Shouldn't get here, as only supported actions should be exposed via canPerformEditingAction
NSString *actionString = NSStringFromSelector(action);
OWSFail(@"'%@' action unsupported for TSInteraction: uniqueId=%@, mediaType=%@",
actionString,
self.interaction.uniqueId,
[self.mediaItem class]);
}
2017-02-16 23:59:40 +01:00
- (TSAttachmentStream *)attachmentStream
{
if (![self.interaction isKindOfClass:[TSMessage class]]) {
return nil;
}
TSMessage *message = (TSMessage *)self.interaction;
if (![message hasAttachments]) {
return nil;
}
OWSAssert(message.attachmentIds.count <= 1);
NSString *attachmentID = message.attachmentIds[0];
TSAttachment *attachment = [TSAttachment fetchObjectWithUniqueID:attachmentID];
if (![attachment isKindOfClass:[TSAttachmentStream class]]) {
return nil;
}
TSAttachmentStream *stream = (TSAttachmentStream *)attachment;
return stream;
}
- (BOOL)isMediaMessage {
return _mediaItem ? YES : NO;
2014-12-18 00:00:10 +01:00
}
- (id<JSQMessageMediaData>)media {
2014-12-18 00:00:10 +01:00
return _mediaItem;
2014-11-25 16:38:33 +01:00
}
- (NSString *)text {
2014-11-25 16:38:33 +01:00
return self.messageBody;
}
- (NSUInteger)messageHash
{
OWSAssert(self.interactionUniqueId);
2017-05-24 04:08:22 +02:00
// messageHash is used as a key in the "message bubble size" cache,
// so messageHash's value must change whenever the message's bubble size
// changes. Incoming messages change size after their attachment's been
// downloaded, so we use the mediaItem's class (which will be nil before
// the attachment is downloaded) to reflect attachment status.
return self.interactionUniqueId.hash ^ [self.mediaItem class].description.hash;
2014-11-27 03:10:00 +01:00
}
- (NSInteger)messageState {
return self.outgoingMessageStatus;
}
- (CGFloat)mediaViewAlpha
{
return (CGFloat)(self.isMediaBeingSent ? 0.75 : 1);
}
- (BOOL)isMediaBeingSent
{
if ([self.interaction isKindOfClass:[TSOutgoingMessage class]]) {
TSOutgoingMessage *outgoingMessage = (TSOutgoingMessage *)self.interaction;
if (outgoingMessage.hasAttachments && outgoingMessage.messageState == TSOutgoingMessageStateAttemptingOut) {
return YES;
}
}
return NO;
}
2017-03-09 07:36:09 +01:00
#pragma mark - Logging
+ (NSString *)tag
{
return [NSString stringWithFormat:@"[%@]", self.class];
}
- (NSString *)tag
{
return self.class.tag;
}
2014-11-25 16:38:33 +01:00
@end
2017-03-29 20:49:26 +02:00
NS_ASSUME_NONNULL_END