mirror of https://github.com/oxen-io/session-ios
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
243 lines
7.9 KiB
Objective-C
243 lines
7.9 KiB
Objective-C
//
|
|
// Copyright (c) 2019 Open Whisper Systems. All rights reserved.
|
|
//
|
|
|
|
#import "OWSGenericAttachmentView.h"
|
|
#import "OWSBezierPathView.h"
|
|
#import "Session-Swift.h"
|
|
#import "UIFont+OWS.h"
|
|
#import "UIView+OWS.h"
|
|
|
|
#import <SignalUtilitiesKit/OWSFormat.h>
|
|
#import <SignalUtilitiesKit/UIColor+OWS.h>
|
|
#import <SessionUtilitiesKit/MIMETypeUtil.h>
|
|
#import <SessionUtilitiesKit/NSString+SSK.h>
|
|
#import <SessionMessagingKit/TSAttachmentStream.h>
|
|
#import <SignalCoreKit/NSString+OWS.h>
|
|
|
|
NS_ASSUME_NONNULL_BEGIN
|
|
|
|
@interface OWSGenericAttachmentView ()
|
|
|
|
@property (nonatomic) TSAttachment *attachment;
|
|
@property (nonatomic, nullable) TSAttachmentStream *attachmentStream;
|
|
@property (nonatomic, weak) id<ConversationViewItem> viewItem;
|
|
@property (nonatomic) BOOL isIncoming;
|
|
@property (nonatomic) UILabel *topLabel;
|
|
@property (nonatomic) UILabel *bottomLabel;
|
|
|
|
@end
|
|
|
|
#pragma mark -
|
|
|
|
@implementation OWSGenericAttachmentView
|
|
|
|
- (instancetype)initWithAttachment:(TSAttachment *)attachment
|
|
isIncoming:(BOOL)isIncoming
|
|
viewItem:(id<ConversationViewItem>)viewItem
|
|
{
|
|
self = [super init];
|
|
|
|
if (self) {
|
|
_attachment = attachment;
|
|
if ([attachment isKindOfClass:[TSAttachmentStream class]]) {
|
|
_attachmentStream = (TSAttachmentStream *)attachment;
|
|
}
|
|
_isIncoming = isIncoming;
|
|
_viewItem = viewItem;
|
|
}
|
|
|
|
return self;
|
|
}
|
|
|
|
#pragma mark -
|
|
|
|
- (CGFloat)hMargin
|
|
{
|
|
return 0.f;
|
|
}
|
|
|
|
- (CGFloat)hSpacing
|
|
{
|
|
return 8.f;
|
|
}
|
|
|
|
- (CGFloat)vMargin
|
|
{
|
|
return 4.f;
|
|
}
|
|
|
|
- (CGSize)measureSizeWithMaxMessageWidth:(CGFloat)maxMessageWidth
|
|
{
|
|
CGSize result = CGSizeZero;
|
|
|
|
CGFloat labelsHeight = ([OWSGenericAttachmentView topLabelFont].lineHeight +
|
|
[OWSGenericAttachmentView bottomLabelFont].lineHeight + [OWSGenericAttachmentView labelVSpacing]);
|
|
CGFloat contentHeight = MAX(self.iconHeight, labelsHeight);
|
|
result.height = contentHeight + self.vMargin * 2;
|
|
|
|
CGFloat labelsWidth
|
|
= MAX([self.topLabel sizeThatFits:CGSizeZero].width, [self.bottomLabel sizeThatFits:CGSizeZero].width);
|
|
CGFloat contentWidth = (self.iconWidth + labelsWidth + self.hSpacing);
|
|
result.width = MIN(maxMessageWidth, contentWidth + self.hMargin * 2);
|
|
|
|
return CGSizeCeil(result);
|
|
}
|
|
|
|
- (CGFloat)iconWidth
|
|
{
|
|
return 36.f;
|
|
}
|
|
|
|
- (CGFloat)iconHeight
|
|
{
|
|
return 48.0f;
|
|
}
|
|
|
|
- (void)createContentsWithConversationStyle:(ConversationStyle *)conversationStyle
|
|
{
|
|
OWSAssertDebug(conversationStyle);
|
|
|
|
self.axis = UILayoutConstraintAxisHorizontal;
|
|
self.alignment = UIStackViewAlignmentCenter;
|
|
self.spacing = self.hSpacing;
|
|
self.layoutMarginsRelativeArrangement = YES;
|
|
self.layoutMargins = UIEdgeInsetsMake(self.vMargin, 0, self.vMargin - 4, 0);
|
|
|
|
// attachment_file
|
|
UIImage *image = [UIImage imageNamed:@"generic-attachment"];
|
|
OWSAssertDebug(image);
|
|
OWSAssertDebug(image.size.width == self.iconWidth);
|
|
OWSAssertDebug(image.size.height == self.iconHeight);
|
|
UIImageView *imageView = [UIImageView new];
|
|
imageView.image = image;
|
|
[self addArrangedSubview:imageView];
|
|
[imageView setContentHuggingHigh];
|
|
|
|
NSString *_Nullable filename = self.attachment.sourceFilename;
|
|
if (!filename) {
|
|
filename = [[self.attachmentStream originalFilePath] lastPathComponent];
|
|
}
|
|
NSString *fileExtension = filename.pathExtension;
|
|
if (fileExtension.length < 1) {
|
|
fileExtension = [MIMETypeUtil fileExtensionForMIMEType:self.attachment.contentType];
|
|
}
|
|
|
|
UILabel *fileTypeLabel = [UILabel new];
|
|
fileTypeLabel.text = fileExtension.localizedUppercaseString;
|
|
fileTypeLabel.textColor = [UIColor ows_gray90Color];
|
|
fileTypeLabel.lineBreakMode = NSLineBreakByTruncatingTail;
|
|
fileTypeLabel.font = [UIFont ows_dynamicTypeCaption1Font].ows_mediumWeight;
|
|
fileTypeLabel.adjustsFontSizeToFitWidth = YES;
|
|
fileTypeLabel.textAlignment = NSTextAlignmentCenter;
|
|
// Center on icon.
|
|
[imageView addSubview:fileTypeLabel];
|
|
[fileTypeLabel autoCenterInSuperview];
|
|
[fileTypeLabel autoSetDimension:ALDimensionWidth toSize:self.iconWidth - 20.f];
|
|
|
|
[self replaceIconWithDownloadProgressIfNecessary:imageView];
|
|
|
|
UIStackView *labelsView = [UIStackView new];
|
|
labelsView.axis = UILayoutConstraintAxisVertical;
|
|
labelsView.spacing = [OWSGenericAttachmentView labelVSpacing];
|
|
labelsView.alignment = UIStackViewAlignmentLeading;
|
|
[self addArrangedSubview:labelsView];
|
|
|
|
NSString *topText = [self.attachment.sourceFilename ows_stripped];
|
|
if (topText.length < 1) {
|
|
topText = [MIMETypeUtil fileExtensionForMIMEType:self.attachment.contentType].localizedUppercaseString;
|
|
}
|
|
if (topText.length < 1) {
|
|
topText = NSLocalizedString(@"GENERIC_ATTACHMENT_LABEL", @"A label for generic attachments.");
|
|
}
|
|
UILabel *topLabel = [UILabel new];
|
|
self.topLabel = topLabel;
|
|
topLabel.text = topText;
|
|
topLabel.textColor = [conversationStyle bubbleTextColorWithIsIncoming:self.isIncoming];
|
|
topLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
|
|
topLabel.font = [OWSGenericAttachmentView topLabelFont];
|
|
[labelsView addArrangedSubview:topLabel];
|
|
|
|
unsigned long long fileSize = 0;
|
|
if (self.attachmentStream) {
|
|
NSError *error;
|
|
fileSize = [[NSFileManager defaultManager] attributesOfItemAtPath:[self.attachmentStream originalFilePath]
|
|
error:&error]
|
|
.fileSize;
|
|
OWSAssertDebug(!error);
|
|
}
|
|
// We don't want to show the file size while the attachment is downloading.
|
|
// To avoid layout jitter when the download completes, we reserve space in
|
|
// the layout using a whitespace string.
|
|
NSString *bottomText = @" ";
|
|
if (fileSize > 0) {
|
|
bottomText = [OWSFormat formatFileSize:fileSize];
|
|
}
|
|
UILabel *bottomLabel = [UILabel new];
|
|
self.bottomLabel = bottomLabel;
|
|
bottomLabel.text = bottomText;
|
|
bottomLabel.textColor = [conversationStyle bubbleSecondaryTextColorWithIsIncoming:self.isIncoming];
|
|
bottomLabel.lineBreakMode = NSLineBreakByTruncatingMiddle;
|
|
bottomLabel.font = [OWSGenericAttachmentView bottomLabelFont];
|
|
[labelsView addArrangedSubview:bottomLabel];
|
|
}
|
|
|
|
- (void)replaceIconWithDownloadProgressIfNecessary:(UIView *)iconView
|
|
{
|
|
if (!self.viewItem.attachmentPointer) {
|
|
return;
|
|
}
|
|
|
|
switch (self.viewItem.attachmentPointer.state) {
|
|
case TSAttachmentPointerStateFailed:
|
|
// We don't need to handle the "tap to retry" state here,
|
|
// only download progress.
|
|
return;
|
|
case TSAttachmentPointerStateEnqueued:
|
|
case TSAttachmentPointerStateDownloading:
|
|
break;
|
|
}
|
|
switch (self.viewItem.attachmentPointer.pointerType) {
|
|
case TSAttachmentPointerTypeRestoring:
|
|
// TODO: Show "restoring" indicator and possibly progress.
|
|
return;
|
|
case TSAttachmentPointerTypeUnknown:
|
|
case TSAttachmentPointerTypeIncoming:
|
|
break;
|
|
}
|
|
NSString *_Nullable uniqueId = self.viewItem.attachmentPointer.uniqueId;
|
|
if (uniqueId.length < 1) {
|
|
OWSFailDebug(@"Missing uniqueId.");
|
|
return;
|
|
}
|
|
|
|
CGSize iconViewSize = [iconView sizeThatFits:CGSizeZero];
|
|
CGFloat downloadViewSize = MIN(iconViewSize.width, iconViewSize.height);
|
|
MediaDownloadView *downloadView =
|
|
[[MediaDownloadView alloc] initWithAttachmentId:uniqueId radius:downloadViewSize * 0.5f];
|
|
iconView.layer.opacity = 0.01f;
|
|
[self addSubview:downloadView];
|
|
[downloadView autoSetDimensionsToSize:CGSizeMake(downloadViewSize, downloadViewSize)];
|
|
[downloadView autoAlignAxis:ALAxisHorizontal toSameAxisOfView:iconView];
|
|
[downloadView autoAlignAxis:ALAxisVertical toSameAxisOfView:iconView];
|
|
}
|
|
|
|
+ (UIFont *)topLabelFont
|
|
{
|
|
return [UIFont systemFontOfSize:LKValues.mediumFontSize];
|
|
}
|
|
|
|
+ (UIFont *)bottomLabelFont
|
|
{
|
|
return [UIFont ows_dynamicTypeCaption1Font];
|
|
}
|
|
|
|
+ (CGFloat)labelVSpacing
|
|
{
|
|
return 2.f;
|
|
}
|
|
|
|
@end
|
|
|
|
NS_ASSUME_NONNULL_END
|