mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Refine appearance of quoted reply message cells.
This commit is contained in:
parent
10b4ade55a
commit
6171505657
|
@ -2,19 +2,17 @@
|
|||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSBubbleView.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class OWSBubbleView;
|
||||
|
||||
@interface OWSBubbleStrokeView : UIView
|
||||
|
||||
@property (nonatomic, weak) OWSBubbleView *bubbleView;
|
||||
@interface OWSBubbleStrokeView : UIView <OWSBubbleViewPartner>
|
||||
|
||||
@property (nonatomic) UIColor *strokeColor;
|
||||
@property (nonatomic) CGFloat strokeThickness;
|
||||
|
||||
- (void)updateLayers;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -12,6 +12,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
@property (nonatomic) CAShapeLayer *shapeLayer;
|
||||
|
||||
@property (nonatomic, weak) OWSBubbleView *bubbleView;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
@ -31,8 +33,6 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
self.shapeLayer = [CAShapeLayer new];
|
||||
[self.layer addSublayer:self.shapeLayer];
|
||||
|
||||
[self updateLayers];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
|
@ -56,7 +56,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
[super setFrame:frame];
|
||||
|
||||
if (didChange || !self.shapeLayer) {
|
||||
if (didChange) {
|
||||
[self updateLayers];
|
||||
}
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
[super setBounds:bounds];
|
||||
|
||||
if (didChange || !self.shapeLayer) {
|
||||
if (didChange) {
|
||||
[self updateLayers];
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSBubbleView.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
extern const CGFloat kOWSMessageCellCornerRadius;
|
||||
|
@ -13,12 +15,20 @@ extern const CGFloat kBubbleThornVInset;
|
|||
extern const CGFloat kBubbleTextHInset;
|
||||
extern const CGFloat kBubbleTextVInset;
|
||||
|
||||
@class OWSBubbleStrokeView;
|
||||
@class OWSBubbleView;
|
||||
|
||||
@protocol OWSBubbleViewPartner <NSObject>
|
||||
|
||||
- (void)updateLayers;
|
||||
|
||||
- (void)setBubbleView:(OWSBubbleView *)bubbleView;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
||||
@interface OWSBubbleView : UIView
|
||||
|
||||
@property (nonatomic, weak, nullable) OWSBubbleStrokeView *bubbleStrokeView;
|
||||
|
||||
@property (nonatomic) BOOL isOutgoing;
|
||||
@property (nonatomic) BOOL hideTail;
|
||||
@property (nonatomic) BOOL isTruncated;
|
||||
|
@ -27,6 +37,14 @@ extern const CGFloat kBubbleTextVInset;
|
|||
|
||||
- (UIBezierPath *)maskPath;
|
||||
|
||||
#pragma mark - Coordination
|
||||
|
||||
- (void)addPartnerView:(id<OWSBubbleViewPartner>)view;
|
||||
|
||||
- (void)clearPartnerViews;
|
||||
|
||||
- (void)updatePartnerViews;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -3,7 +3,6 @@
|
|||
//
|
||||
|
||||
#import "OWSBubbleView.h"
|
||||
#import "OWSBubbleStrokeView.h"
|
||||
#import <SignalMessaging/UIView+OWS.h>
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
@ -22,6 +21,8 @@ const CGFloat kBubbleTextVInset = 10.f;
|
|||
@property (nonatomic) CAShapeLayer *maskLayer;
|
||||
@property (nonatomic) CAShapeLayer *shapeLayer;
|
||||
|
||||
@property (nonatomic, readonly) NSMutableArray<id<OWSBubbleViewPartner>> *partnerViews;
|
||||
|
||||
@end
|
||||
|
||||
#pragma mark -
|
||||
|
@ -41,7 +42,7 @@ const CGFloat kBubbleTextVInset = 10.f;
|
|||
self.maskLayer = [CAShapeLayer new];
|
||||
self.layer.mask = self.maskLayer;
|
||||
|
||||
[self updateLayers];
|
||||
_partnerViews = [NSMutableArray new];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
@ -52,7 +53,7 @@ const CGFloat kBubbleTextVInset = 10.f;
|
|||
|
||||
_isOutgoing = isOutgoing;
|
||||
|
||||
if (didChange || !self.shapeLayer) {
|
||||
if (didChange) {
|
||||
[self updateLayers];
|
||||
}
|
||||
}
|
||||
|
@ -63,7 +64,7 @@ const CGFloat kBubbleTextVInset = 10.f;
|
|||
|
||||
_hideTail = hideTail;
|
||||
|
||||
if (didChange || !self.shapeLayer) {
|
||||
if (didChange) {
|
||||
[self updateLayers];
|
||||
}
|
||||
}
|
||||
|
@ -74,7 +75,7 @@ const CGFloat kBubbleTextVInset = 10.f;
|
|||
|
||||
_isTruncated = isTruncated;
|
||||
|
||||
if (didChange || !self.shapeLayer) {
|
||||
if (didChange) {
|
||||
[self updateLayers];
|
||||
}
|
||||
}
|
||||
|
@ -87,13 +88,13 @@ const CGFloat kBubbleTextVInset = 10.f;
|
|||
|
||||
[super setFrame:frame];
|
||||
|
||||
if (didChangeSize || !self.shapeLayer) {
|
||||
if (didChangeSize) {
|
||||
[self updateLayers];
|
||||
}
|
||||
|
||||
// We always need to inform the "bubble stroke view" (if any) if our
|
||||
// frame/bounds/center changes. Its contents are not in local coordinates.
|
||||
[self.bubbleStrokeView updateLayers];
|
||||
[self updatePartnerViews];
|
||||
}
|
||||
|
||||
- (void)setBounds:(CGRect)bounds
|
||||
|
@ -104,13 +105,13 @@ const CGFloat kBubbleTextVInset = 10.f;
|
|||
|
||||
[super setBounds:bounds];
|
||||
|
||||
if (didChangeSize || !self.shapeLayer) {
|
||||
if (didChangeSize) {
|
||||
[self updateLayers];
|
||||
}
|
||||
|
||||
// We always need to inform the "bubble stroke view" (if any) if our
|
||||
// frame/bounds/center changes. Its contents are not in local coordinates.
|
||||
[self.bubbleStrokeView updateLayers];
|
||||
[self updatePartnerViews];
|
||||
}
|
||||
|
||||
- (void)setCenter:(CGPoint)center
|
||||
|
@ -119,7 +120,7 @@ const CGFloat kBubbleTextVInset = 10.f;
|
|||
|
||||
// We always need to inform the "bubble stroke view" (if any) if our
|
||||
// frame/bounds/center changes. Its contents are not in local coordinates.
|
||||
[self.bubbleStrokeView updateLayers];
|
||||
[self updatePartnerViews];
|
||||
}
|
||||
|
||||
- (void)setBubbleColor:(nullable UIColor *)bubbleColor
|
||||
|
@ -211,6 +212,33 @@ const CGFloat kBubbleTextVInset = 10.f;
|
|||
return bezierPath;
|
||||
}
|
||||
|
||||
#pragma mark - Coordination
|
||||
|
||||
- (void)addPartnerView:(id<OWSBubbleViewPartner>)partnerView
|
||||
{
|
||||
OWSAssert(self.partnerViews);
|
||||
|
||||
[partnerView setBubbleView:self];
|
||||
|
||||
[self.partnerViews addObject:partnerView];
|
||||
}
|
||||
|
||||
- (void)clearPartnerViews
|
||||
{
|
||||
OWSAssert(self.partnerViews);
|
||||
|
||||
[self.partnerViews removeAllObjects];
|
||||
}
|
||||
|
||||
- (void)updatePartnerViews
|
||||
{
|
||||
[self layoutIfNeeded];
|
||||
|
||||
for (id<OWSBubbleViewPartner> partnerView in self.partnerViews) {
|
||||
[partnerView updateLayers];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -10,6 +10,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
+ (NSString *)cellReuseIdentifier;
|
||||
|
||||
+ (UIFont *)defaultTextMessageFont;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -147,11 +147,16 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
return NSStringFromClass([self class]);
|
||||
}
|
||||
|
||||
+ (UIFont *)defaultTextMessageFont
|
||||
{
|
||||
return [UIFont ows_dynamicTypeBodyFont];
|
||||
}
|
||||
|
||||
- (UIFont *)textMessageFont
|
||||
{
|
||||
OWSAssert(DisplayableText.kMaxJumbomojiCount == 5);
|
||||
|
||||
CGFloat basePointSize = [UIFont ows_dynamicTypeBodyFont].pointSize;
|
||||
CGFloat basePointSize = self.class.defaultTextMessageFont.pointSize;
|
||||
switch (self.displayableBodyText.jumbomojiCount) {
|
||||
case 0:
|
||||
break;
|
||||
|
@ -361,8 +366,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
if (self.isQuotedReply) {
|
||||
OWSAssert(!lastSubview);
|
||||
|
||||
TSMessage *message = (TSMessage *)self.viewItem.interaction;
|
||||
OWSQuotedMessageView *quotedMessageView =
|
||||
[[OWSQuotedMessageView alloc] initWithViewItem:self.viewItem textMessageFont:self.textMessageFont];
|
||||
[OWSQuotedMessageView quotedMessageViewForConversation:message.quotedMessage
|
||||
displayableQuotedText:self.viewItem.displayableQuotedText];
|
||||
[quotedMessageView createContents];
|
||||
[self.bubbleView addSubview:quotedMessageView];
|
||||
|
||||
|
@ -381,6 +388,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}
|
||||
lastSubview = quotedMessageView;
|
||||
bottomMargin = 0;
|
||||
|
||||
[self.bubbleView addPartnerView:quotedMessageView];
|
||||
}
|
||||
|
||||
UIView *_Nullable bodyMediaView = nil;
|
||||
|
@ -471,8 +480,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[bubbleStrokeView autoPinEdge:ALEdgeBottom toEdge:ALEdgeBottom ofView:bodyMediaView];
|
||||
[bubbleStrokeView autoPinEdge:ALEdgeLeft toEdge:ALEdgeLeft ofView:bodyMediaView];
|
||||
[bubbleStrokeView autoPinEdge:ALEdgeRight toEdge:ALEdgeRight ofView:bodyMediaView];
|
||||
self.bubbleView.bubbleStrokeView = bubbleStrokeView;
|
||||
OWSAssert(self.bubbleView.bubbleStrokeView);
|
||||
|
||||
[self.bubbleView addPartnerView:bubbleStrokeView];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1174,8 +1183,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
return CGSizeZero;
|
||||
}
|
||||
|
||||
TSMessage *message = (TSMessage *)self.viewItem.interaction;
|
||||
OWSQuotedMessageView *quotedMessageView =
|
||||
[[OWSQuotedMessageView alloc] initWithViewItem:self.viewItem textMessageFont:self.textMessageFont];
|
||||
[OWSQuotedMessageView quotedMessageViewForConversation:message.quotedMessage
|
||||
displayableQuotedText:self.viewItem.displayableQuotedText];
|
||||
const int maxMessageWidth = [self maxMessageWidthForContentWidth:contentWidth];
|
||||
CGSize result = [quotedMessageView sizeForMaxWidth:maxMessageWidth - kBubbleThornSideInset];
|
||||
result.width += kBubbleThornSideInset;
|
||||
|
@ -1324,7 +1335,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
self.bubbleView.hidden = YES;
|
||||
self.bubbleView.bubbleColor = nil;
|
||||
self.bubbleView.bubbleStrokeView = nil;
|
||||
[self.bubbleView clearPartnerViews];
|
||||
|
||||
for (UIView *subview in self.bubbleView.subviews) {
|
||||
[subview removeFromSuperview];
|
||||
|
|
|
@ -2,25 +2,28 @@
|
|||
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||
//
|
||||
|
||||
#import "OWSBubbleView.h"
|
||||
|
||||
NS_ASSUME_NONNULL_BEGIN
|
||||
|
||||
@class ConversationViewItem;
|
||||
@class DisplayableText;
|
||||
@class TSQuotedMessage;
|
||||
|
||||
@interface OWSQuotedMessageView : UIView
|
||||
@interface OWSQuotedMessageView : UIView <OWSBubbleViewPartner>
|
||||
|
||||
- (instancetype)init NS_UNAVAILABLE;
|
||||
|
||||
- (instancetype)initWithViewItem:(ConversationViewItem *)viewItem
|
||||
// quotedMessage:(TSQuotedMessage *)quotedMessage
|
||||
textMessageFont:(UIFont *)textMessageFont;
|
||||
|
||||
// Only needs to be called if we're going to render this instance.
|
||||
- (void)createContents;
|
||||
|
||||
// Measurement
|
||||
- (CGSize)sizeForMaxWidth:(CGFloat)maxWidth;
|
||||
|
||||
+ (OWSQuotedMessageView *)quotedMessageViewForConversation:(TSQuotedMessage *)quotedMessage
|
||||
displayableQuotedText:(nullable DisplayableText *)displayableQuotedText;
|
||||
|
||||
+ (OWSQuotedMessageView *)quotedMessageViewForPreview:(TSQuotedMessage *)quotedMessage;
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
#import "OWSQuotedMessageView.h"
|
||||
#import "ConversationViewItem.h"
|
||||
#import "Environment.h"
|
||||
#import "OWSMessageCell.h"
|
||||
#import "Signal-Swift.h"
|
||||
#import <SignalMessaging/OWSContactsManager.h>
|
||||
#import <SignalMessaging/SignalMessaging-Swift.h>
|
||||
|
@ -18,16 +19,47 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
@interface OWSQuotedMessageView ()
|
||||
|
||||
@property (nonatomic, readonly) ConversationViewItem *viewItem;
|
||||
@property (nonatomic, readonly) TSQuotedMessage *quotedMessage;
|
||||
@property (nonatomic, nullable, readonly) DisplayableText *displayableQuotedText;
|
||||
|
||||
@property (nonatomic, readonly) UIFont *textMessageFont;
|
||||
|
||||
@property (nonatomic, readonly) UIColor *strokeColor;
|
||||
@property (nonatomic, readonly) CGFloat strokeThickness;
|
||||
|
||||
// TODO: Replace with a bubble stroke view.
|
||||
@property (nonatomic) CAShapeLayer *shapeLayer;
|
||||
|
||||
@property (nonatomic, weak) OWSBubbleView *bubbleView;
|
||||
|
||||
@end
|
||||
|
||||
@implementation OWSQuotedMessageView
|
||||
|
||||
- (instancetype)initWithViewItem:(ConversationViewItem *)viewItem
|
||||
// quotedMessage:(TSQuotedMessage *)quotedMessage
|
||||
textMessageFont:(UIFont *)textMessageFont
|
||||
+ (OWSQuotedMessageView *)quotedMessageViewForConversation:(TSQuotedMessage *)quotedMessage
|
||||
displayableQuotedText:(nullable DisplayableText *)displayableQuotedText
|
||||
{
|
||||
OWSAssert(quotedMessage);
|
||||
|
||||
return
|
||||
[[OWSQuotedMessageView alloc] initWithQuotedMessage:quotedMessage displayableQuotedText:displayableQuotedText];
|
||||
}
|
||||
|
||||
+ (OWSQuotedMessageView *)quotedMessageViewForPreview:(TSQuotedMessage *)quotedMessage
|
||||
{
|
||||
OWSAssert(quotedMessage);
|
||||
|
||||
DisplayableText *_Nullable displayableQuotedText = nil;
|
||||
if (quotedMessage.body.length > 0) {
|
||||
displayableQuotedText = [DisplayableText displayableText:quotedMessage.body];
|
||||
}
|
||||
|
||||
return
|
||||
[[OWSQuotedMessageView alloc] initWithQuotedMessage:quotedMessage displayableQuotedText:displayableQuotedText];
|
||||
}
|
||||
|
||||
- (instancetype)initWithQuotedMessage:(TSQuotedMessage *)quotedMessage
|
||||
displayableQuotedText:(nullable DisplayableText *)displayableQuotedText
|
||||
{
|
||||
self = [super init];
|
||||
|
||||
|
@ -35,37 +67,31 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
return self;
|
||||
}
|
||||
|
||||
OWSAssert(viewItem);
|
||||
// OWSAssert(quotedMessage);
|
||||
OWSAssert(textMessageFont);
|
||||
OWSAssert(quotedMessage);
|
||||
OWSAssert(displayableQuotedText);
|
||||
|
||||
_viewItem = viewItem;
|
||||
// _quotedMessage = quotedMessage;
|
||||
_textMessageFont = textMessageFont;
|
||||
_quotedMessage = quotedMessage;
|
||||
_displayableQuotedText = displayableQuotedText;
|
||||
_textMessageFont = OWSMessageCell.defaultTextMessageFont;
|
||||
_strokeColor = OWSMessagesBubbleImageFactory.bubbleColorIncoming;
|
||||
_strokeThickness = 1.f;
|
||||
|
||||
self.shapeLayer = [CAShapeLayer new];
|
||||
[self.layer addSublayer:self.shapeLayer];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (BOOL)isIncoming
|
||||
{
|
||||
return self.viewItem.interaction.interactionType == OWSInteractionType_IncomingMessage;
|
||||
}
|
||||
|
||||
- (BOOL)hasQuotedAttachmentThumbnail
|
||||
{
|
||||
// This should always be valid for the appropriate cell types.
|
||||
OWSAssert(self.viewItem);
|
||||
|
||||
return (self.viewItem.hasQuotedAttachment &&
|
||||
[TSAttachmentStream hasThumbnailForMimeType:self.viewItem.quotedAttachmentMimetype]);
|
||||
return (self.quotedMessage.contentType.length > 0 &&
|
||||
[TSAttachmentStream hasThumbnailForMimeType:self.quotedMessage.contentType]);
|
||||
}
|
||||
|
||||
#pragma mark -
|
||||
|
||||
- (void)createContents
|
||||
{
|
||||
OWSAssert(self.viewItem.isQuotedReply);
|
||||
|
||||
self.backgroundColor = [UIColor whiteColor];
|
||||
self.userInteractionEnabled = NO;
|
||||
self.layoutMargins = UIEdgeInsetsZero;
|
||||
|
@ -91,14 +117,15 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
}
|
||||
|
||||
OWSContactsManager *contactsManager = Environment.current.contactsManager;
|
||||
NSString *quotedAuthor = [contactsManager displayNameForPhoneIdentifier:self.viewItem.quotedRecipientId];
|
||||
NSString *quotedAuthor = [contactsManager displayNameForPhoneIdentifier:self.quotedMessage.authorId];
|
||||
|
||||
UILabel *quotedAuthorLabel = [UILabel new];
|
||||
{
|
||||
quotedAuthorLabel.text = quotedAuthor;
|
||||
quotedAuthorLabel.font = self.quotedAuthorFont;
|
||||
quotedAuthorLabel.textColor
|
||||
= (self.isIncoming ? [UIColor colorWithRGBHex:0xd84315] : [UIColor colorWithRGBHex:0x007884]);
|
||||
// TODO:
|
||||
quotedAuthorLabel.textColor = [UIColor ows_darkGrayColor];
|
||||
// = (self.isIncoming ? [UIColor colorWithRGBHex:0xd84315] : [UIColor colorWithRGBHex:0x007884]);
|
||||
quotedAuthorLabel.numberOfLines = 1;
|
||||
quotedAuthorLabel.lineBreakMode = NSLineBreakByTruncatingTail;
|
||||
[self addSubview:quotedAuthorLabel];
|
||||
|
@ -135,8 +162,12 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
[stripeAndTextContainer setCompressionResistanceLow];
|
||||
|
||||
// Stripe.
|
||||
BOOL isIncomingQuote
|
||||
= ![NSObject isNullableObject:self.quotedMessage.authorId equalTo:TSAccountManager.localNumber];
|
||||
UIColor *stripeColor = (isIncomingQuote ? OWSMessagesBubbleImageFactory.bubbleColorIncoming
|
||||
: OWSMessagesBubbleImageFactory.bubbleColorOutgoingSent);
|
||||
UIView *quoteStripView = [UIView containerView];
|
||||
quoteStripView.backgroundColor = (self.isIncoming ? [UIColor whiteColor] : [UIColor colorWithRGBHex:0x007884]);
|
||||
quoteStripView.backgroundColor = stripeColor;
|
||||
quoteStripView.userInteractionEnabled = NO;
|
||||
[stripeAndTextContainer addSubview:quoteStripView];
|
||||
[quoteStripView autoPinHeightToSuperview];
|
||||
|
@ -163,15 +194,8 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
// TODO: Class method?
|
||||
- (CGSize)sizeForMaxWidth:(CGFloat)maxWidth
|
||||
{
|
||||
OWSAssert(self.viewItem);
|
||||
OWSAssert([self.viewItem.interaction isKindOfClass:[TSMessage class]]);
|
||||
|
||||
CGSize result = CGSizeZero;
|
||||
|
||||
if (!self.viewItem.isQuotedReply) {
|
||||
return result;
|
||||
}
|
||||
|
||||
result.width += self.quotedContentHInset;
|
||||
|
||||
CGFloat thumbnailHeight = 0.f;
|
||||
|
@ -192,7 +216,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
CGFloat maxQuotedAuthorWidth = maxWidth - result.width;
|
||||
|
||||
OWSContactsManager *contactsManager = Environment.current.contactsManager;
|
||||
NSString *quotedAuthor = [contactsManager displayNameForPhoneIdentifier:self.viewItem.quotedRecipientId];
|
||||
NSString *quotedAuthor = [contactsManager displayNameForPhoneIdentifier:self.quotedMessage.authorId];
|
||||
|
||||
UILabel *quotedAuthorLabel = [UILabel new];
|
||||
quotedAuthorLabel.text = quotedAuthor;
|
||||
|
@ -253,10 +277,10 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
|
||||
- (NSString *)quotedSnippet
|
||||
{
|
||||
if (self.viewItem.hasQuotedText && self.viewItem.displayableQuotedText.displayText.length > 0) {
|
||||
return self.viewItem.displayableQuotedText.displayText;
|
||||
if (self.displayableQuotedText.displayText.length > 0) {
|
||||
return self.displayableQuotedText.displayText;
|
||||
} else {
|
||||
NSString *mimeType = self.viewItem.quotedAttachmentMimetype;
|
||||
NSString *mimeType = self.quotedMessage.contentType;
|
||||
|
||||
if (mimeType.length > 0) {
|
||||
return [TSAttachment emojiForMimeType:mimeType];
|
||||
|
@ -299,7 +323,7 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
// TODO:
|
||||
- (CGFloat)quotedReplyStripeThickness
|
||||
{
|
||||
return 3.f;
|
||||
return 2.f;
|
||||
}
|
||||
|
||||
// TODO:
|
||||
|
@ -342,6 +366,101 @@ NS_ASSUME_NONNULL_BEGIN
|
|||
return 8.f;
|
||||
}
|
||||
|
||||
#pragma mark - Stroke
|
||||
|
||||
//- (instancetype)init
|
||||
//{
|
||||
// self = [super init];
|
||||
// if (!self) {
|
||||
// return self;
|
||||
// }
|
||||
//
|
||||
// self.opaque = NO;
|
||||
// self.backgroundColor = [UIColor clearColor];
|
||||
//
|
||||
//
|
||||
// [self updateLayers];
|
||||
//
|
||||
// return self;
|
||||
//}
|
||||
|
||||
- (void)setStrokeColor:(UIColor *)strokeColor
|
||||
{
|
||||
_strokeColor = strokeColor;
|
||||
|
||||
[self updateLayers];
|
||||
}
|
||||
|
||||
- (void)setStrokeThickness:(CGFloat)strokeThickness
|
||||
{
|
||||
_strokeThickness = strokeThickness;
|
||||
|
||||
[self updateLayers];
|
||||
}
|
||||
|
||||
- (void)setFrame:(CGRect)frame
|
||||
{
|
||||
BOOL didChange = !CGRectEqualToRect(self.frame, frame);
|
||||
|
||||
[super setFrame:frame];
|
||||
|
||||
if (didChange) {
|
||||
[self updateLayers];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setBounds:(CGRect)bounds
|
||||
{
|
||||
BOOL didChange = !CGRectEqualToRect(self.bounds, bounds);
|
||||
|
||||
[super setBounds:bounds];
|
||||
|
||||
if (didChange) {
|
||||
[self updateLayers];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)setCenter:(CGPoint)center
|
||||
{
|
||||
[super setCenter:center];
|
||||
|
||||
[self updateLayers];
|
||||
}
|
||||
|
||||
- (void)updateLayers
|
||||
{
|
||||
if (!self.shapeLayer) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Don't fill the shape layer; we just want a stroke around the border.
|
||||
self.shapeLayer.fillColor = [UIColor clearColor].CGColor;
|
||||
|
||||
self.clipsToBounds = YES;
|
||||
|
||||
if (!self.bubbleView) {
|
||||
return;
|
||||
}
|
||||
|
||||
self.shapeLayer.strokeColor = self.strokeColor.CGColor;
|
||||
self.shapeLayer.lineWidth = self.strokeThickness;
|
||||
self.shapeLayer.zPosition = 100.f;
|
||||
|
||||
UIBezierPath *bezierPath = [UIBezierPath new];
|
||||
|
||||
UIBezierPath *boundsBezierPath = [UIBezierPath bezierPathWithRect:self.bounds];
|
||||
[bezierPath appendPath:boundsBezierPath];
|
||||
|
||||
UIBezierPath *bubbleBezierPath = [self.bubbleView maskPath];
|
||||
// We need to convert between coordinate systems using layers, not views.
|
||||
CGPoint bubbleOffset = [self.layer convertPoint:CGPointZero fromLayer:self.bubbleView.layer];
|
||||
CGAffineTransform transform = CGAffineTransformMakeTranslation(bubbleOffset.x, bubbleOffset.y);
|
||||
[bubbleBezierPath applyTransform:transform];
|
||||
[bezierPath appendPath:bubbleBezierPath];
|
||||
|
||||
self.shapeLayer.path = bezierPath.CGPath;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
NS_ASSUME_NONNULL_END
|
||||
|
|
|
@ -2299,6 +2299,14 @@ typedef enum : NSUInteger {
|
|||
|
||||
- (void)scrollDownButtonTapped
|
||||
{
|
||||
#ifdef DEBUG
|
||||
CGPoint contentOffset = self.collectionView.contentOffset;
|
||||
contentOffset.y += self.collectionView.height
|
||||
- (self.collectionView.contentInset.top + self.collectionView.contentInset.bottom);
|
||||
[self.collectionView setContentOffset:contentOffset animated:NO];
|
||||
return;
|
||||
#endif
|
||||
|
||||
NSIndexPath *indexPathOfUnreadMessagesIndicator = [self indexPathOfUnreadMessagesIndicator];
|
||||
if (indexPathOfUnreadMessagesIndicator != nil) {
|
||||
NSInteger unreadRow = indexPathOfUnreadMessagesIndicator.row;
|
||||
|
|
|
@ -9,7 +9,8 @@ import SignalServiceKit
|
|||
@objc
|
||||
public class OWSMessagesBubbleImageFactory: NSObject {
|
||||
|
||||
static let shared = OWSMessagesBubbleImageFactory()
|
||||
@objc
|
||||
public static let shared = OWSMessagesBubbleImageFactory()
|
||||
|
||||
private let jsqFactory = JSQMessagesBubbleImageFactory()!
|
||||
|
||||
|
@ -57,12 +58,16 @@ public class OWSMessagesBubbleImageFactory: NSObject {
|
|||
}
|
||||
}
|
||||
|
||||
@objc
|
||||
public static let bubbleColorIncoming = UIColor.jsq_messageBubbleLightGray()!
|
||||
|
||||
@objc
|
||||
public static let bubbleColorOutgoingUnsent = UIColor.gray
|
||||
|
||||
@objc
|
||||
public static let bubbleColorOutgoingSending = UIColor.ows_fadedBlue
|
||||
|
||||
@objc
|
||||
public static let bubbleColorOutgoingSent = UIColor.ows_materialBlue
|
||||
|
||||
public func bubbleColor(message: TSMessage) -> UIColor {
|
||||
|
|
Loading…
Reference in a new issue