mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Handle oversize text messages and arbitrary attachments.
// FREEBIE
This commit is contained in:
parent
bf1a790372
commit
80fbc093d9
23 changed files with 388 additions and 49 deletions
|
@ -17,6 +17,7 @@
|
|||
344F2F671E57A932000D9322 /* UIViewController+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 344F2F661E57A932000D9322 /* UIViewController+OWS.m */; };
|
||||
34535D821E256BE9008A4747 /* UIView+OWS.m in Sources */ = {isa = PBXBuildFile; fileRef = 34535D811E256BE9008A4747 /* UIView+OWS.m */; };
|
||||
345671011E89A5F1006EE662 /* ThreadUtil.m in Sources */ = {isa = PBXBuildFile; fileRef = 345671001E89A5F1006EE662 /* ThreadUtil.m */; };
|
||||
3456710A1E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m in Sources */ = {isa = PBXBuildFile; fileRef = 345671091E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m */; };
|
||||
34802DD71E899CFB0032EA1D /* DebugUITableViewController.m in Sources */ = {isa = PBXBuildFile; fileRef = 34802DD61E899CFB0032EA1D /* DebugUITableViewController.m */; };
|
||||
348A08421E6A044E0057E290 /* MessagesViewController.xib in Resources */ = {isa = PBXBuildFile; fileRef = 348A08411E6A044E0057E290 /* MessagesViewController.xib */; };
|
||||
348A08441E6A1D2C0057E290 /* OWSMessagesToolbarContentView.xib in Resources */ = {isa = PBXBuildFile; fileRef = 348A08431E6A1D2C0057E290 /* OWSMessagesToolbarContentView.xib */; };
|
||||
|
@ -404,6 +405,8 @@
|
|||
34535D811E256BE9008A4747 /* UIView+OWS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "UIView+OWS.m"; sourceTree = "<group>"; };
|
||||
345670FF1E89A5F1006EE662 /* ThreadUtil.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ThreadUtil.h; sourceTree = "<group>"; };
|
||||
345671001E89A5F1006EE662 /* ThreadUtil.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = ThreadUtil.m; sourceTree = "<group>"; };
|
||||
345671081E8A9F5D006EE662 /* TSGenericAttachmentAdapter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TSGenericAttachmentAdapter.h; sourceTree = "<group>"; };
|
||||
345671091E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = TSGenericAttachmentAdapter.m; sourceTree = "<group>"; };
|
||||
34802DD51E899CFB0032EA1D /* DebugUITableViewController.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUITableViewController.h; sourceTree = "<group>"; };
|
||||
34802DD61E899CFB0032EA1D /* DebugUITableViewController.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUITableViewController.m; sourceTree = "<group>"; };
|
||||
348A08411E6A044E0057E290 /* MessagesViewController.xib */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = file.xib; path = MessagesViewController.xib; sourceTree = "<group>"; };
|
||||
|
@ -1428,6 +1431,8 @@
|
|||
4CE0E3751B95453C007210CF /* TSAnimatedAdapter.h */,
|
||||
4CE0E3761B954546007210CF /* TSAnimatedAdapter.m */,
|
||||
B6D3CBCE1C1376BE00C039DF /* TSContentAdapters.h */,
|
||||
345671081E8A9F5D006EE662 /* TSGenericAttachmentAdapter.h */,
|
||||
345671091E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m */,
|
||||
B62D53F51A23CCAD009AAF82 /* TSMessageAdapter.h */,
|
||||
B62D53F61A23CCAD009AAF82 /* TSMessageAdapter.m */,
|
||||
B6A3EB491A423B3800B2236B /* TSPhotoAdapter.h */,
|
||||
|
@ -2156,6 +2161,7 @@
|
|||
458E38311D6682450094BD24 /* OWSQRCodeScanningViewController.m in Sources */,
|
||||
451A13B11E13DED2000A50FD /* CallNotificationsAdapter.swift in Sources */,
|
||||
76EB062418170B33006006FC /* PriorityQueue.m in Sources */,
|
||||
3456710A1E8A9F5D006EE662 /* TSGenericAttachmentAdapter.m in Sources */,
|
||||
450DF2091E0DD2C6003D14BE /* UserNotificationsAdaptee.swift in Sources */,
|
||||
B6BADBE71B88D1AC0086A80D /* LockInteractionController.m in Sources */,
|
||||
76EB061A18170B33006006FC /* DiscardingLog.m in Sources */,
|
||||
|
|
23
Signal/Images.xcassets/file-black-60.imageset/Contents.json
vendored
Normal file
23
Signal/Images.xcassets/file-black-60.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "file-icon-60@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "file-icon-60@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "file-icon-60@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
BIN
Signal/Images.xcassets/file-black-60.imageset/file-icon-60@1x.png
vendored
Normal file
BIN
Signal/Images.xcassets/file-black-60.imageset/file-icon-60@1x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
Signal/Images.xcassets/file-black-60.imageset/file-icon-60@2x.png
vendored
Normal file
BIN
Signal/Images.xcassets/file-black-60.imageset/file-icon-60@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.3 KiB |
BIN
Signal/Images.xcassets/file-black-60.imageset/file-icon-60@3x.png
vendored
Normal file
BIN
Signal/Images.xcassets/file-black-60.imageset/file-icon-60@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
23
Signal/Images.xcassets/file-white-60.imageset/Contents.json
vendored
Normal file
23
Signal/Images.xcassets/file-white-60.imageset/Contents.json
vendored
Normal file
|
@ -0,0 +1,23 @@
|
|||
{
|
||||
"images" : [
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "file-white-60@1x.png",
|
||||
"scale" : "1x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "file-white-60@2x.png",
|
||||
"scale" : "2x"
|
||||
},
|
||||
{
|
||||
"idiom" : "universal",
|
||||
"filename" : "file-white-60@3x.png",
|
||||
"scale" : "3x"
|
||||
}
|
||||
],
|
||||
"info" : {
|
||||
"version" : 1,
|
||||
"author" : "xcode"
|
||||
}
|
||||
}
|
BIN
Signal/Images.xcassets/file-white-60.imageset/file-white-60@1x.png
vendored
Normal file
BIN
Signal/Images.xcassets/file-white-60.imageset/file-white-60@1x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 1.7 KiB |
BIN
Signal/Images.xcassets/file-white-60.imageset/file-white-60@2x.png
vendored
Normal file
BIN
Signal/Images.xcassets/file-white-60.imageset/file-white-60@2x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.4 KiB |
BIN
Signal/Images.xcassets/file-white-60.imageset/file-white-60@3x.png
vendored
Normal file
BIN
Signal/Images.xcassets/file-white-60.imageset/file-white-60@3x.png
vendored
Normal file
Binary file not shown.
After Width: | Height: | Size: 2.9 KiB |
|
@ -1,8 +1,11 @@
|
|||
// Copyright (c) 2016 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSMessagesBubblesSizeCalculator.h"
|
||||
#import "OWSCall.h"
|
||||
#import "OWSDisplayedMessageCollectionViewCell.h"
|
||||
#import "TSGenericAttachmentAdapter.h"
|
||||
#import "TSMessageAdapter.h"
|
||||
#import "UIFont+OWS.h"
|
||||
#import "tgmath.h" // generic math allows fmax to handle CGFLoat correctly on 32 & 64bit.
|
||||
|
|
|
@ -79,6 +79,9 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
- (void)dealloc
|
||||
{
|
||||
[_maskLayer removeFromSuperlayer];
|
||||
[_progressView removeFromSuperview];
|
||||
|
||||
[[NSNotificationCenter defaultCenter] removeObserver:self];
|
||||
}
|
||||
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
|
||||
- (instancetype)initWithAttachment:(TSAttachmentStream *)attachment incoming:(BOOL)incoming;
|
||||
|
||||
- (BOOL)isImage;
|
||||
- (BOOL)isAudio;
|
||||
- (BOOL)isVideo;
|
||||
|
||||
@property NSString *attachmentId;
|
||||
@property NSData *fileData;
|
||||
|
||||
|
|
|
@ -94,20 +94,6 @@
|
|||
return [self ows_adjustBubbleSize:[super mediaViewDisplaySize] forImage:self.image];
|
||||
}
|
||||
|
||||
- (BOOL)isImage {
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isAudio {
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isVideo {
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - OWSMessageEditing Protocol
|
||||
|
||||
- (BOOL)canPerformEditingAction:(SEL)action
|
||||
|
|
|
@ -0,0 +1,14 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSMessageEditing.h"
|
||||
#import <JSQMessagesViewController/JSQMediaItem.h>
|
||||
|
||||
@class TSAttachmentStream;
|
||||
|
||||
@interface TSGenericAttachmentAdapter : JSQMediaItem <OWSMessageEditing>
|
||||
|
||||
- (instancetype)initWithAttachment:(TSAttachmentStream *)attachment incoming:(BOOL)incoming;
|
||||
|
||||
@end
|
|
@ -0,0 +1,196 @@
|
|||
//
|
||||
// Copyright (c) 2017 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "TSGenericAttachmentAdapter.h"
|
||||
#import "AttachmentUploadView.h"
|
||||
#import "TSAttachmentStream.h"
|
||||
#import "UIColor+JSQMessages.h"
|
||||
#import "UIColor+OWS.h"
|
||||
#import "UIFont+OWS.h"
|
||||
#import <JSQMessagesViewController/JSQMessagesBubbleImage.h>
|
||||
#import <JSQMessagesViewController/JSQMessagesBubbleImageFactory.h>
|
||||
#import <MobileCoreServices/MobileCoreServices.h>
|
||||
#import <SignalServiceKit/MimeTypeUtil.h>
|
||||
|
||||
@interface TSGenericAttachmentAdapter ()
|
||||
|
||||
@property (nonatomic) UIView *cachedMediaView;
|
||||
@property (nonatomic) TSAttachmentStream *attachment;
|
||||
@property (nonatomic) AttachmentUploadView *attachmentUploadView;
|
||||
@property (nonatomic) BOOL incoming;
|
||||
@property (nonatomic) NSString *attachmentId;
|
||||
|
||||
@end
|
||||
|
||||
@implementation TSGenericAttachmentAdapter
|
||||
|
||||
- (instancetype)initWithAttachment:(TSAttachmentStream *)attachment incoming:(BOOL)incoming
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
if (self) {
|
||||
_attachment = attachment;
|
||||
_attachmentId = attachment.uniqueId;
|
||||
_incoming = incoming;
|
||||
}
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)clearCachedMediaViews
|
||||
{
|
||||
[super clearCachedMediaViews];
|
||||
_cachedMediaView = nil;
|
||||
}
|
||||
|
||||
- (void)setAppliesMediaViewMaskAsOutgoing:(BOOL)appliesMediaViewMaskAsOutgoing
|
||||
{
|
||||
[super setAppliesMediaViewMaskAsOutgoing:appliesMediaViewMaskAsOutgoing];
|
||||
_cachedMediaView = nil;
|
||||
}
|
||||
|
||||
// TODO: Should we override hash or mediaHash?
|
||||
- (NSUInteger)mediaHash
|
||||
{
|
||||
return [self.attachment.uniqueId hash];
|
||||
}
|
||||
|
||||
#pragma mark - JSQMessageMediaData protocol
|
||||
|
||||
- (CGFloat)iconSize
|
||||
{
|
||||
return 60.f;
|
||||
}
|
||||
|
||||
- (CGFloat)hMargin
|
||||
{
|
||||
return 10.f;
|
||||
}
|
||||
|
||||
- (CGFloat)vMargin
|
||||
{
|
||||
return 10.f;
|
||||
}
|
||||
|
||||
- (UIFont *)attachmentLabelFont
|
||||
{
|
||||
return [UIFont ows_regularFontWithSize:11.f];
|
||||
}
|
||||
|
||||
- (UIFont *)fileTypeLabelFont
|
||||
{
|
||||
return [UIFont ows_mediumFontWithSize:16.f];
|
||||
}
|
||||
|
||||
- (UIView *)mediaView
|
||||
{
|
||||
if (_cachedMediaView == nil) {
|
||||
CGSize viewSize = [self mediaViewDisplaySize];
|
||||
UIColor *textColor = (self.incoming ? [UIColor blackColor] : [UIColor whiteColor]);
|
||||
|
||||
JSQMessagesBubbleImageFactory *bubbleFactory = [[JSQMessagesBubbleImageFactory alloc] init];
|
||||
JSQMessagesBubbleImage *bubbleImageData = (self.incoming
|
||||
? [bubbleFactory incomingMessagesBubbleImageWithColor:[UIColor jsq_messageBubbleLightGrayColor]]
|
||||
: [bubbleFactory outgoingMessagesBubbleImageWithColor:[UIColor ows_materialBlueColor]]);
|
||||
UIImage *bubbleImage = [bubbleImageData messageBubbleImage];
|
||||
OWSAssert(bubbleImage);
|
||||
UIImageView *bubbleImageView = [[UIImageView alloc] initWithImage:bubbleImage];
|
||||
_cachedMediaView = bubbleImageView;
|
||||
_cachedMediaView.frame = CGRectMake(0.f, 0.f, viewSize.width, viewSize.height);
|
||||
|
||||
const CGFloat kBubbleTailWidth = 6.f;
|
||||
CGRect contentFrame = CGRectMake(self.incoming ? kBubbleTailWidth : 0.f,
|
||||
self.vMargin,
|
||||
viewSize.width - kBubbleTailWidth,
|
||||
viewSize.height - self.vMargin * 2.f);
|
||||
|
||||
UIImage *image = [UIImage imageNamed:(self.incoming ? @"file-black-60" : @"file-white-60")];
|
||||
OWSAssert(image);
|
||||
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
|
||||
CGRect iconFrame = CGRectMake(round(contentFrame.origin.x + (contentFrame.size.width - self.iconSize) * 0.5f),
|
||||
round(contentFrame.origin.y),
|
||||
self.iconSize,
|
||||
self.iconSize);
|
||||
imageView.frame = iconFrame;
|
||||
[_cachedMediaView addSubview:imageView];
|
||||
|
||||
NSString *fileExtension = [MIMETypeUtil fileExtensionForMIMEType:self.attachment.contentType];
|
||||
if (fileExtension.length < 1) {
|
||||
fileExtension = NSLocalizedString(@"GENERIC_ATTACHMENT_DEFAULT_TYPE",
|
||||
@"A default label for attachment whose file extension cannot be determined.");
|
||||
}
|
||||
|
||||
UILabel *fileTypeLabel = [UILabel new];
|
||||
fileTypeLabel.text = fileExtension.uppercaseString;
|
||||
fileTypeLabel.textColor = textColor;
|
||||
fileTypeLabel.lineBreakMode = NSLineBreakByTruncatingTail;
|
||||
fileTypeLabel.font = [self fileTypeLabelFont];
|
||||
CGRect fileTypeLabelFrame = CGRectZero;
|
||||
fileTypeLabelFrame.size = [fileTypeLabel sizeThatFits:CGSizeZero];
|
||||
fileTypeLabelFrame.size.width = floor(MIN(self.iconSize * 0.5f, fileTypeLabelFrame.size.width));
|
||||
// Center on icon.
|
||||
fileTypeLabelFrame.origin.x
|
||||
= round(iconFrame.origin.x + (iconFrame.size.width - fileTypeLabelFrame.size.width) * 0.5f);
|
||||
fileTypeLabelFrame.origin.y
|
||||
= round(iconFrame.origin.y + (iconFrame.size.height - fileTypeLabelFrame.size.height) * 0.5f + 5);
|
||||
fileTypeLabel.frame = fileTypeLabelFrame;
|
||||
[_cachedMediaView addSubview:fileTypeLabel];
|
||||
|
||||
UILabel *attachmentLabel = [UILabel new];
|
||||
attachmentLabel.text = NSLocalizedString(@"GENERIC_ATTACHMENT_LABEL", @"A label for generic attachments.");
|
||||
attachmentLabel.textColor = [textColor colorWithAlphaComponent:0.85f];
|
||||
attachmentLabel.lineBreakMode = NSLineBreakByTruncatingTail;
|
||||
attachmentLabel.font = [self attachmentLabelFont];
|
||||
[attachmentLabel sizeToFit];
|
||||
CGRect attachmentLabelFrame = CGRectZero;
|
||||
attachmentLabelFrame.size = attachmentLabel.bounds.size;
|
||||
attachmentLabelFrame.origin.x
|
||||
= round(contentFrame.origin.x + (contentFrame.size.width - attachmentLabelFrame.size.width) * 0.5f);
|
||||
attachmentLabelFrame.origin.y
|
||||
= round(contentFrame.origin.y + contentFrame.size.height - attachmentLabelFrame.size.height);
|
||||
attachmentLabel.frame = attachmentLabelFrame;
|
||||
[_cachedMediaView addSubview:attachmentLabel];
|
||||
|
||||
if (!self.incoming) {
|
||||
self.attachmentUploadView = [[AttachmentUploadView alloc] initWithAttachment:self.attachment
|
||||
superview:_cachedMediaView
|
||||
attachmentStateCallback:nil];
|
||||
}
|
||||
}
|
||||
|
||||
return _cachedMediaView;
|
||||
}
|
||||
|
||||
- (CGSize)mediaViewDisplaySize
|
||||
{
|
||||
const CGFloat kVSpacing = 1.f;
|
||||
return CGSizeMake(100, ceil(self.iconSize + self.attachmentLabelFont.lineHeight + kVSpacing + self.vMargin * 2));
|
||||
}
|
||||
|
||||
#pragma mark - OWSMessageEditing Protocol
|
||||
|
||||
- (BOOL)canPerformEditingAction:(SEL)action
|
||||
{
|
||||
if (action == @selector(copy:)) {
|
||||
NSString *utiType = [MIMETypeUtil utiTypeForMIMEType:self.attachment.contentType];
|
||||
return utiType.length > 0;
|
||||
}
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (void)performEditingAction:(SEL)action
|
||||
{
|
||||
if (action == @selector(copy:)) {
|
||||
NSString *utiType = [MIMETypeUtil utiTypeForMIMEType:self.attachment.contentType];
|
||||
OWSAssert(utiType.length > 0);
|
||||
NSData *data = [NSData dataWithContentsOfURL:self.attachment.mediaURL];
|
||||
[UIPasteboard.generalPasteboard setData:data forPasteboardType:utiType];
|
||||
} else {
|
||||
// Shouldn't get here, as only supported actions should be exposed via canPerformEditingAction
|
||||
NSString *actionString = NSStringFromSelector(action);
|
||||
DDLogError(@"'%@' action unsupported for %@: attachmentId=%@", actionString, [self class], self.attachmentId);
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
|
@ -4,20 +4,21 @@
|
|||
|
||||
#import "AttachmentSharing.h"
|
||||
#import "OWSCall.h"
|
||||
#import "Signal-Swift.h"
|
||||
#import "TSAttachmentPointer.h"
|
||||
#import "TSAttachmentStream.h"
|
||||
#import "TSCall.h"
|
||||
#import "TSContactThread.h"
|
||||
#import "TSContentAdapters.h"
|
||||
#import "TSErrorMessage.h"
|
||||
#import "TSGenericAttachmentAdapter.h"
|
||||
#import "TSGroupThread.h"
|
||||
#import "TSIncomingMessage.h"
|
||||
#import "TSInfoMessage.h"
|
||||
#import "TSOutgoingMessage.h"
|
||||
#import "Signal-Swift.h"
|
||||
#import "TSOversizeTextAttachmentAdapter.h"
|
||||
#import <MobileCoreServices/MobileCoreServices.h>
|
||||
|
||||
|
||||
@interface TSMessageAdapter ()
|
||||
|
||||
// ---
|
||||
|
@ -131,7 +132,25 @@
|
|||
|
||||
if ([attachment isKindOfClass:[TSAttachmentStream class]]) {
|
||||
TSAttachmentStream *stream = (TSAttachmentStream *)attachment;
|
||||
if ([stream isAnimated]) {
|
||||
if ([attachment.contentType isEqualToString:OWSMimeTypeOversizeTextMessage]) {
|
||||
NSData *textData = [NSData dataWithContentsOfURL:stream.mediaURL];
|
||||
NSString *fullText = [[NSString alloc] initWithData:textData encoding:NSUTF8StringEncoding];
|
||||
// TODO: Tune this value.
|
||||
const NSUInteger kMaxTextDisplayLength = 256;
|
||||
NSString *displayText = fullText;
|
||||
if (fullText.length > kMaxTextDisplayLength) {
|
||||
// Trim whitespace before _AND_ after slicing the snipper from the string.
|
||||
NSString *snippet =
|
||||
[[[fullText stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]
|
||||
substringWithRange:NSMakeRange(0, kMaxTextDisplayLength)]
|
||||
stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
|
||||
displayText =
|
||||
[NSString stringWithFormat:NSLocalizedString(@"OVERSIZE_TEXT_DISPLAY_FORMAT",
|
||||
@"A display format for oversize text messages."),
|
||||
snippet];
|
||||
}
|
||||
adapter.messageBody = displayText;
|
||||
} else if ([stream isAnimated]) {
|
||||
adapter.mediaItem =
|
||||
[[TSAnimatedAdapter alloc] initWithAttachment:stream incoming:isIncomingAttachment];
|
||||
adapter.mediaItem.appliesMediaViewMaskAsOutgoing =
|
||||
|
@ -143,13 +162,19 @@
|
|||
adapter.mediaItem.appliesMediaViewMaskAsOutgoing =
|
||||
[interaction isKindOfClass:[TSOutgoingMessage class]];
|
||||
break;
|
||||
} else {
|
||||
} else if ([stream isVideo]) {
|
||||
adapter.mediaItem = [[TSVideoAttachmentAdapter alloc]
|
||||
initWithAttachment:stream
|
||||
incoming:[interaction isKindOfClass:[TSIncomingMessage class]]];
|
||||
adapter.mediaItem.appliesMediaViewMaskAsOutgoing =
|
||||
[interaction isKindOfClass:[TSOutgoingMessage class]];
|
||||
break;
|
||||
} else {
|
||||
adapter.mediaItem = [[TSGenericAttachmentAdapter alloc]
|
||||
initWithAttachment:stream
|
||||
incoming:[interaction isKindOfClass:[TSIncomingMessage class]]];
|
||||
adapter.mediaItem.appliesMediaViewMaskAsOutgoing = YES;
|
||||
break;
|
||||
}
|
||||
} else if ([attachment isKindOfClass:[TSAttachmentPointer class]]) {
|
||||
TSAttachmentPointer *pointer = (TSAttachmentPointer *)attachment;
|
||||
|
|
|
@ -11,10 +11,6 @@
|
|||
|
||||
- (instancetype)initWithAttachment:(TSAttachmentStream *)attachment incoming:(BOOL)incoming;
|
||||
|
||||
- (BOOL)isImage;
|
||||
- (BOOL)isAudio;
|
||||
- (BOOL)isVideo;
|
||||
|
||||
@property TSAttachmentStream *attachment;
|
||||
@property NSString *attachmentId;
|
||||
|
||||
|
|
|
@ -80,20 +80,6 @@
|
|||
return [self ows_adjustBubbleSize:[super mediaViewDisplaySize] forImage:self.image];
|
||||
}
|
||||
|
||||
- (BOOL)isImage {
|
||||
return YES;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isAudio {
|
||||
return NO;
|
||||
}
|
||||
|
||||
|
||||
- (BOOL)isVideo {
|
||||
return NO;
|
||||
}
|
||||
|
||||
#pragma mark - OWSMessageEditing Protocol
|
||||
|
||||
- (BOOL)canPerformEditingAction:(SEL)action
|
||||
|
|
|
@ -15,7 +15,6 @@
|
|||
|
||||
- (instancetype)initWithAttachment:(TSAttachmentStream *)attachment incoming:(BOOL)incoming;
|
||||
|
||||
- (BOOL)isImage;
|
||||
- (BOOL)isAudio;
|
||||
- (BOOL)isVideo;
|
||||
- (void)setAudioProgressFromFloat:(float)progress;
|
||||
|
|
|
@ -46,10 +46,6 @@
|
|||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isImage {
|
||||
return NO;
|
||||
}
|
||||
|
||||
- (BOOL)isAudio {
|
||||
return [MIMETypeUtil isSupportedAudioMIMEType:_contentType];
|
||||
}
|
||||
|
|
|
@ -3,8 +3,9 @@
|
|||
//
|
||||
|
||||
#import "DebugUITableViewController.h"
|
||||
#import "ThreadUtil.h"
|
||||
#import "Environment.h"
|
||||
#import "Signal-Swift.h"
|
||||
#import "ThreadUtil.h"
|
||||
#import <SignalServiceKit/TSThread.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
@ -220,7 +221,7 @@ NSString * const kDebugUITableCellIdentifier = @"kDebugUITableCellIdentifier";
|
|||
return self.class.tag;
|
||||
}
|
||||
|
||||
#pragma mark - Factory and presentation
|
||||
#pragma mark - Factory Methods
|
||||
|
||||
+ (void)presentDebugUIForThread:(TSThread *)thread
|
||||
fromViewController:(UIViewController *)fromViewController {
|
||||
|
@ -232,11 +233,24 @@ NSString * const kDebugUITableCellIdentifier = @"kDebugUITableCellIdentifier";
|
|||
|
||||
[contents addSection:[OWSTableSection sectionWithTitle:@"Messages View"
|
||||
items:@[
|
||||
[OWSTableItem actionWithTitle:@"Send 100 messages"
|
||||
[OWSTableItem actionWithTitle:@"Send 10 messages (1/sec.)"
|
||||
actionBlock:^{
|
||||
[DebugUITableViewController sendTextMessage:10
|
||||
thread:thread];
|
||||
}],
|
||||
[OWSTableItem actionWithTitle:@"Send 100 messages (1/sec.)"
|
||||
actionBlock:^{
|
||||
[DebugUITableViewController sendTextMessage:100
|
||||
thread:thread];
|
||||
}],
|
||||
[OWSTableItem actionWithTitle:@"Send text/x-signal-plain"
|
||||
actionBlock:^{
|
||||
[DebugUITableViewController sendOversizeTextMessage:thread];
|
||||
}],
|
||||
[OWSTableItem actionWithTitle:@"Send unknown/mimetype"
|
||||
actionBlock:^{
|
||||
[DebugUITableViewController sendUnknownMimetypeAttachment:thread];
|
||||
}],
|
||||
]]];
|
||||
|
||||
DebugUITableViewController *viewController = [DebugUITableViewController new];
|
||||
|
@ -259,6 +273,39 @@ NSString * const kDebugUITableCellIdentifier = @"kDebugUITableCellIdentifier";
|
|||
});
|
||||
}
|
||||
|
||||
+ (void)sendOversizeTextMessage:(TSThread *)thread {
|
||||
OWSMessageSender *messageSender = [Environment getCurrent].messageSender;
|
||||
NSString *message = @"Lorem ipsum dolor sit amet, consectetur adipiscing elit. Suspendisse consequat, ligula et tincidunt mattis, nisl risus ultricies justo, vitae dictum augue risus vel ante. Suspendisse convallis bibendum lectus. Etiam molestie nisi ac orci sodales sollicitudin vitae eu quam. Morbi lacinia scelerisque risus. Quisque sagittis mauris enim, ac vestibulum dui commodo quis. Nullam at commodo nisl, ut pulvinar dui. Nunc tempus volutpat sagittis. Vestibulum eget maximus sem, sit amet tristique ex posuere.";
|
||||
SignalAttachment *attachment = [SignalAttachment oversizeTextAttachmentWithText:message];
|
||||
[ThreadUtil sendMessageWithAttachment:attachment
|
||||
inThread:thread
|
||||
messageSender:messageSender];
|
||||
}
|
||||
|
||||
+ (NSData*)createRandomNSDataOfSize:(size_t)size
|
||||
{
|
||||
OWSAssert(size % 4 == 0);
|
||||
|
||||
NSMutableData* data = [NSMutableData dataWithCapacity:size];
|
||||
for (size_t i = 0; i < size / 4; ++i)
|
||||
{
|
||||
u_int32_t randomBits = arc4random();
|
||||
[data appendBytes:(void *)&randomBits length:4];
|
||||
}
|
||||
return data;
|
||||
}
|
||||
|
||||
+ (void)sendUnknownMimetypeAttachment:(TSThread *)thread {
|
||||
OWSMessageSender *messageSender = [Environment getCurrent].messageSender;
|
||||
SignalAttachment *attachment = [SignalAttachment genericAttachmentWithData:[self createRandomNSDataOfSize:256]
|
||||
dataUTI:SignalAttachment.kUnknownTestAttachmentUTI];
|
||||
[ThreadUtil sendMessageWithAttachment:attachment
|
||||
inThread:thread
|
||||
messageSender:messageSender];
|
||||
}
|
||||
|
||||
#pragma mark - Presentation
|
||||
|
||||
- (void)presentFromViewController:(UIViewController *)fromViewController {
|
||||
OWSAssert(fromViewController);
|
||||
|
||||
|
|
|
@ -69,6 +69,9 @@ class SignalAttachment: NSObject {
|
|||
// See: https://developer.apple.com/library/content/documentation/Miscellaneous/Reference/UTIRef/Articles/System-DeclaredUniformTypeIdentifiers.html
|
||||
let dataUTI: String
|
||||
|
||||
static let kOversizeTextAttachmentUTI = "org.whispersystems.oversize-text-attachment"
|
||||
static let kUnknownTestAttachmentUTI = "org.whispersystems.unknown"
|
||||
|
||||
var error: SignalAttachmentError? {
|
||||
didSet {
|
||||
AssertIsOnMainThread()
|
||||
|
@ -137,6 +140,12 @@ class SignalAttachment: NSObject {
|
|||
// Returns the MIME type for this attachment or nil if no MIME type
|
||||
// can be identified.
|
||||
var mimeType: String? {
|
||||
if dataUTI == SignalAttachment.kOversizeTextAttachmentUTI {
|
||||
return OWSMimeTypeOversizeTextMessage
|
||||
}
|
||||
if dataUTI == SignalAttachment.kUnknownTestAttachmentUTI {
|
||||
return OWSMimeTypeUnknownForTests
|
||||
}
|
||||
let mimeType = UTTypeCopyPreferredTagWithClass(dataUTI as CFString, kUTTagClassMIMEType)
|
||||
guard mimeType != nil else {
|
||||
return nil
|
||||
|
@ -147,6 +156,12 @@ class SignalAttachment: NSObject {
|
|||
// Returns the file extension for this attachment or nil if no file extension
|
||||
// can be identified.
|
||||
var fileExtension: String? {
|
||||
if dataUTI == SignalAttachment.kOversizeTextAttachmentUTI ||
|
||||
dataUTI == SignalAttachment.kUnknownTestAttachmentUTI {
|
||||
assert(false)
|
||||
return ""
|
||||
}
|
||||
|
||||
guard let fileExtension = UTTypeCopyPreferredTagWithClass(dataUTI as CFString,
|
||||
kUTTagClassFilenameExtension) else {
|
||||
return nil
|
||||
|
@ -508,6 +523,19 @@ class SignalAttachment: NSObject {
|
|||
maxFileSize : kMaxFileSizeAudio)
|
||||
}
|
||||
|
||||
// MARK: Oversize Text Attachments
|
||||
|
||||
// Factory method for oversize text attachments.
|
||||
//
|
||||
// NOTE: The attachment returned by this method may not be valid.
|
||||
// Check the attachment's error property.
|
||||
public class func oversizeTextAttachment(text: String?) -> SignalAttachment {
|
||||
return newAttachment(data : text?.data(using: .utf8),
|
||||
dataUTI : kOversizeTextAttachmentUTI,
|
||||
validUTISet : nil,
|
||||
maxFileSize : kMaxFileSizeGeneric)
|
||||
}
|
||||
|
||||
// MARK: Generic Attachments
|
||||
|
||||
// Factory method for generic attachments.
|
||||
|
|
|
@ -97,6 +97,9 @@
|
|||
/* No comment provided by engineer. */
|
||||
"ATTACHMENT_QUEUED" = "New attachment queued for retrieval.";
|
||||
|
||||
/* A message indicating that an attachment of unknown type was received. */
|
||||
"ATTACHMENT_UNKNOWN_TYPE" = "Unknown attachment received";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"AUDIO_PERMISSION_MESSAGE" = "Signal requires access to your microphone to work properly. You can grant this permission in the Settings app >> Privacy >> Microphone >> Signal";
|
||||
|
||||
|
@ -325,6 +328,12 @@
|
|||
/* Accessibilty label for finishing new group */
|
||||
"FINISH_GROUP_CREATION_LABEL" = "Finish creating group";
|
||||
|
||||
/* A default label for attachment whose file extension cannot be determined. */
|
||||
"GENERIC_ATTACHMENT_DEFAULT_TYPE" = "?";
|
||||
|
||||
/* A label for generic attachments. */
|
||||
"GENERIC_ATTACHMENT_LABEL" = "Attachment";
|
||||
|
||||
/* No comment provided by engineer. */
|
||||
"GROUP_AVATAR_CHANGED" = "Avatar changed. ";
|
||||
|
||||
|
@ -601,6 +610,9 @@
|
|||
/* No comment provided by engineer. */
|
||||
"OUTGOING_INCOMPLETE_CALL" = "Incomplete outgoing call";
|
||||
|
||||
/* A display format for oversize text messages. */
|
||||
"OVERSIZE_TEXT_DISPLAY_FORMAT" = "%@… [Tap For More]";
|
||||
|
||||
/* Alert body when verifying with {{contact name}} */
|
||||
"PRIVACY_VERIFICATION_FAILED_I_HAVE_WRONG_KEY_FOR_THEM" = "This doesn't look like your safety number with %@. Are you verifying the correct contact?";
|
||||
|
||||
|
|
Loading…
Reference in a new issue