mirror of
https://github.com/oxen-io/session-ios.git
synced 2023-12-13 21:30:14 +01:00
Bubble collapse.
This commit is contained in:
parent
3d07dc7c5b
commit
c8012d3891
|
@ -216,6 +216,7 @@
|
||||||
34DB0BED2011548B007B313F /* OWSDatabaseConverterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DB0BEC2011548B007B313F /* OWSDatabaseConverterTest.m */; };
|
34DB0BED2011548B007B313F /* OWSDatabaseConverterTest.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DB0BEC2011548B007B313F /* OWSDatabaseConverterTest.m */; };
|
||||||
34DBF003206BD5A500025978 /* OWSMessageTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DBEFFF206BD5A400025978 /* OWSMessageTextView.m */; };
|
34DBF003206BD5A500025978 /* OWSMessageTextView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DBEFFF206BD5A400025978 /* OWSMessageTextView.m */; };
|
||||||
34DBF004206BD5A500025978 /* OWSBubbleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DBF001206BD5A500025978 /* OWSBubbleView.m */; };
|
34DBF004206BD5A500025978 /* OWSBubbleView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DBF001206BD5A500025978 /* OWSBubbleView.m */; };
|
||||||
|
34DBF007206C3CB200025978 /* OWSBubbleStrokeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 34DBF006206C3CB200025978 /* OWSBubbleStrokeView.m */; };
|
||||||
34E3E5681EC4B19400495BAC /* AudioProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E3E5671EC4B19400495BAC /* AudioProgressView.swift */; };
|
34E3E5681EC4B19400495BAC /* AudioProgressView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 34E3E5671EC4B19400495BAC /* AudioProgressView.swift */; };
|
||||||
34E3EF0D1EFC235B007F6822 /* DebugUIDiskUsage.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */; };
|
34E3EF0D1EFC235B007F6822 /* DebugUIDiskUsage.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */; };
|
||||||
34E3EF101EFC2684007F6822 /* DebugUIPage.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E3EF0F1EFC2684007F6822 /* DebugUIPage.m */; };
|
34E3EF101EFC2684007F6822 /* DebugUIPage.m in Sources */ = {isa = PBXBuildFile; fileRef = 34E3EF0F1EFC2684007F6822 /* DebugUIPage.m */; };
|
||||||
|
@ -841,6 +842,8 @@
|
||||||
34DBF000206BD5A400025978 /* OWSMessageTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessageTextView.h; sourceTree = "<group>"; };
|
34DBF000206BD5A400025978 /* OWSMessageTextView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSMessageTextView.h; sourceTree = "<group>"; };
|
||||||
34DBF001206BD5A500025978 /* OWSBubbleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBubbleView.m; sourceTree = "<group>"; };
|
34DBF001206BD5A500025978 /* OWSBubbleView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBubbleView.m; sourceTree = "<group>"; };
|
||||||
34DBF002206BD5A500025978 /* OWSBubbleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBubbleView.h; sourceTree = "<group>"; };
|
34DBF002206BD5A500025978 /* OWSBubbleView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBubbleView.h; sourceTree = "<group>"; };
|
||||||
|
34DBF005206C3CB100025978 /* OWSBubbleStrokeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = OWSBubbleStrokeView.h; sourceTree = "<group>"; };
|
||||||
|
34DBF006206C3CB200025978 /* OWSBubbleStrokeView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = OWSBubbleStrokeView.m; sourceTree = "<group>"; };
|
||||||
34E3E5671EC4B19400495BAC /* AudioProgressView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AudioProgressView.swift; sourceTree = "<group>"; };
|
34E3E5671EC4B19400495BAC /* AudioProgressView.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AudioProgressView.swift; sourceTree = "<group>"; };
|
||||||
34E3EF0B1EFC235B007F6822 /* DebugUIDiskUsage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIDiskUsage.h; sourceTree = "<group>"; };
|
34E3EF0B1EFC235B007F6822 /* DebugUIDiskUsage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DebugUIDiskUsage.h; sourceTree = "<group>"; };
|
||||||
34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIDiskUsage.m; sourceTree = "<group>"; };
|
34E3EF0C1EFC235B007F6822 /* DebugUIDiskUsage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = DebugUIDiskUsage.m; sourceTree = "<group>"; };
|
||||||
|
@ -1651,6 +1654,8 @@
|
||||||
34D1F0971F867BFC0066283D /* ConversationViewCell.m */,
|
34D1F0971F867BFC0066283D /* ConversationViewCell.m */,
|
||||||
34D1F0B81F8800D90066283D /* OWSAudioMessageView.h */,
|
34D1F0B81F8800D90066283D /* OWSAudioMessageView.h */,
|
||||||
34D1F0B91F8800D90066283D /* OWSAudioMessageView.m */,
|
34D1F0B91F8800D90066283D /* OWSAudioMessageView.m */,
|
||||||
|
34DBF005206C3CB100025978 /* OWSBubbleStrokeView.h */,
|
||||||
|
34DBF006206C3CB200025978 /* OWSBubbleStrokeView.m */,
|
||||||
34DBF002206BD5A500025978 /* OWSBubbleView.h */,
|
34DBF002206BD5A500025978 /* OWSBubbleView.h */,
|
||||||
34DBF001206BD5A500025978 /* OWSBubbleView.m */,
|
34DBF001206BD5A500025978 /* OWSBubbleView.m */,
|
||||||
34D1F09A1F867BFC0066283D /* OWSContactOffersCell.h */,
|
34D1F09A1F867BFC0066283D /* OWSContactOffersCell.h */,
|
||||||
|
@ -3135,6 +3140,7 @@
|
||||||
3461293E1FD1D72B00532771 /* ExperienceUpgradeFinder.swift in Sources */,
|
3461293E1FD1D72B00532771 /* ExperienceUpgradeFinder.swift in Sources */,
|
||||||
34D1F0BD1F8D108C0066283D /* AttachmentUploadView.m in Sources */,
|
34D1F0BD1F8D108C0066283D /* AttachmentUploadView.m in Sources */,
|
||||||
452EC6DF205E9E30000E787C /* MediaGalleryViewController.swift in Sources */,
|
452EC6DF205E9E30000E787C /* MediaGalleryViewController.swift in Sources */,
|
||||||
|
34DBF007206C3CB200025978 /* OWSBubbleStrokeView.m in Sources */,
|
||||||
34D1F0BA1F8800D90066283D /* OWSAudioMessageView.m in Sources */,
|
34D1F0BA1F8800D90066283D /* OWSAudioMessageView.m in Sources */,
|
||||||
34D8C02B1ED3685800188D7C /* DebugUIContacts.m in Sources */,
|
34D8C02B1ED3685800188D7C /* DebugUIContacts.m in Sources */,
|
||||||
45C9DEB81DF4E35A0065CA84 /* WebRTCCallMessageHandler.swift in Sources */,
|
45C9DEB81DF4E35A0065CA84 /* WebRTCCallMessageHandler.swift in Sources */,
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@class OWSBubbleView;
|
||||||
|
|
||||||
|
@interface OWSBubbleStrokeView : UIView
|
||||||
|
|
||||||
|
@property (nonatomic, weak) OWSBubbleView *bubbleView;
|
||||||
|
|
||||||
|
@property (nonatomic) UIColor *strokeColor;
|
||||||
|
@property (nonatomic) CGFloat strokeThickness;
|
||||||
|
|
||||||
|
- (void)updateLayers;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_END
|
|
@ -0,0 +1,114 @@
|
||||||
|
//
|
||||||
|
// Copyright (c) 2018 Open Whisper Systems. All rights reserved.
|
||||||
|
//
|
||||||
|
|
||||||
|
#import "OWSBubbleStrokeView.h"
|
||||||
|
#import "OWSBubbleView.h"
|
||||||
|
#import <SignalMessaging/UIView+OWS.h>
|
||||||
|
|
||||||
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
|
||||||
|
@interface OWSBubbleStrokeView ()
|
||||||
|
|
||||||
|
@property (nonatomic) CAShapeLayer *shapeLayer;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
|
@implementation OWSBubbleStrokeView
|
||||||
|
|
||||||
|
- (instancetype)init
|
||||||
|
{
|
||||||
|
self = [super init];
|
||||||
|
if (!self) {
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
self.opaque = NO;
|
||||||
|
self.backgroundColor = [UIColor clearColor];
|
||||||
|
|
||||||
|
return self;
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setStrokeColor:(UIColor *)strokeColor
|
||||||
|
{
|
||||||
|
_strokeColor = strokeColor;
|
||||||
|
|
||||||
|
[self updateLayers];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setStrokeThickness:(CGFloat)strokeThickness
|
||||||
|
{
|
||||||
|
_strokeThickness = strokeThickness;
|
||||||
|
|
||||||
|
[self updateLayers];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setFrame:(CGRect)frame
|
||||||
|
{
|
||||||
|
BOOL didChange = !CGSizeEqualToSize(self.frame.size, frame.size);
|
||||||
|
|
||||||
|
[super setFrame:frame];
|
||||||
|
|
||||||
|
if (didChange || !self.shapeLayer) {
|
||||||
|
[self updateLayers];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setBounds:(CGRect)bounds
|
||||||
|
{
|
||||||
|
BOOL didChange = !CGSizeEqualToSize(self.bounds.size, bounds.size);
|
||||||
|
|
||||||
|
[super setBounds:bounds];
|
||||||
|
|
||||||
|
if (didChange || !self.shapeLayer) {
|
||||||
|
[self updateLayers];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setCenter:(CGPoint)center
|
||||||
|
{
|
||||||
|
[super setCenter:center];
|
||||||
|
|
||||||
|
[self updateLayers];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)updateLayers
|
||||||
|
{
|
||||||
|
if (!self.shapeLayer) {
|
||||||
|
self.shapeLayer = [CAShapeLayer new];
|
||||||
|
[self.layer addSublayer:self.shapeLayer];
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
|
@ -13,16 +13,19 @@ extern const CGFloat kBubbleThornVInset;
|
||||||
extern const CGFloat kBubbleTextHInset;
|
extern const CGFloat kBubbleTextHInset;
|
||||||
extern const CGFloat kBubbleTextVInset;
|
extern const CGFloat kBubbleTextVInset;
|
||||||
|
|
||||||
|
@class OWSBubbleStrokeView;
|
||||||
|
|
||||||
@interface OWSBubbleView : UIView
|
@interface OWSBubbleView : UIView
|
||||||
|
|
||||||
|
@property (nonatomic, weak, nullable) OWSBubbleStrokeView *bubbleStrokeView;
|
||||||
|
|
||||||
@property (nonatomic) BOOL isOutgoing;
|
@property (nonatomic) BOOL isOutgoing;
|
||||||
@property (nonatomic) BOOL hideTail;
|
@property (nonatomic) BOOL hideTail;
|
||||||
|
|
||||||
@property (nonatomic) CAShapeLayer *maskLayer;
|
|
||||||
@property (nonatomic) CAShapeLayer *shapeLayer;
|
|
||||||
|
|
||||||
@property (nonatomic, nullable) UIColor *bubbleColor;
|
@property (nonatomic, nullable) UIColor *bubbleColor;
|
||||||
|
|
||||||
|
- (UIBezierPath *)maskPath;
|
||||||
|
|
||||||
@end
|
@end
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_END
|
NS_ASSUME_NONNULL_END
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
//
|
//
|
||||||
|
|
||||||
#import "OWSBubbleView.h"
|
#import "OWSBubbleView.h"
|
||||||
|
#import "OWSBubbleStrokeView.h"
|
||||||
#import <SignalMessaging/UIView+OWS.h>
|
#import <SignalMessaging/UIView+OWS.h>
|
||||||
|
|
||||||
NS_ASSUME_NONNULL_BEGIN
|
NS_ASSUME_NONNULL_BEGIN
|
||||||
|
@ -17,6 +18,15 @@ const CGFloat kBubbleThornVInset = 0;
|
||||||
const CGFloat kBubbleTextHInset = 10.f;
|
const CGFloat kBubbleTextHInset = 10.f;
|
||||||
const CGFloat kBubbleTextVInset = 10.f;
|
const CGFloat kBubbleTextVInset = 10.f;
|
||||||
|
|
||||||
|
@interface OWSBubbleView ()
|
||||||
|
|
||||||
|
@property (nonatomic) CAShapeLayer *maskLayer;
|
||||||
|
@property (nonatomic) CAShapeLayer *shapeLayer;
|
||||||
|
|
||||||
|
@end
|
||||||
|
|
||||||
|
#pragma mark -
|
||||||
|
|
||||||
@implementation OWSBubbleView
|
@implementation OWSBubbleView
|
||||||
|
|
||||||
- (void)setIsOutgoing:(BOOL)isOutgoing
|
- (void)setIsOutgoing:(BOOL)isOutgoing
|
||||||
|
@ -26,7 +36,7 @@ const CGFloat kBubbleTextVInset = 10.f;
|
||||||
_isOutgoing = isOutgoing;
|
_isOutgoing = isOutgoing;
|
||||||
|
|
||||||
if (didChange || !self.shapeLayer) {
|
if (didChange || !self.shapeLayer) {
|
||||||
[self updateMask];
|
[self updateLayers];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -37,8 +47,11 @@ const CGFloat kBubbleTextVInset = 10.f;
|
||||||
[super setFrame:frame];
|
[super setFrame:frame];
|
||||||
|
|
||||||
if (didChange || !self.shapeLayer) {
|
if (didChange || !self.shapeLayer) {
|
||||||
[self updateMask];
|
[self updateLayers];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We need to inform the "bubble stroke view" (if any) any time our frame changes.
|
||||||
|
[self.bubbleStrokeView updateLayers];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setBounds:(CGRect)bounds
|
- (void)setBounds:(CGRect)bounds
|
||||||
|
@ -48,8 +61,19 @@ const CGFloat kBubbleTextVInset = 10.f;
|
||||||
[super setBounds:bounds];
|
[super setBounds:bounds];
|
||||||
|
|
||||||
if (didChange || !self.shapeLayer) {
|
if (didChange || !self.shapeLayer) {
|
||||||
[self updateMask];
|
[self updateLayers];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// We need to inform the "bubble stroke view" (if any) any time our frame changes.
|
||||||
|
[self.bubbleStrokeView updateLayers];
|
||||||
|
}
|
||||||
|
|
||||||
|
- (void)setCenter:(CGPoint)center
|
||||||
|
{
|
||||||
|
[super setCenter:center];
|
||||||
|
|
||||||
|
// We need to inform the "bubble stroke view" (if any) any time our frame changes.
|
||||||
|
[self.bubbleStrokeView updateLayers];
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)setBubbleColor:(nullable UIColor *)bubbleColor
|
- (void)setBubbleColor:(nullable UIColor *)bubbleColor
|
||||||
|
@ -57,12 +81,12 @@ const CGFloat kBubbleTextVInset = 10.f;
|
||||||
_bubbleColor = bubbleColor;
|
_bubbleColor = bubbleColor;
|
||||||
|
|
||||||
if (!self.shapeLayer) {
|
if (!self.shapeLayer) {
|
||||||
[self updateMask];
|
[self updateLayers];
|
||||||
}
|
}
|
||||||
self.shapeLayer.fillColor = bubbleColor.CGColor;
|
self.shapeLayer.fillColor = bubbleColor.CGColor;
|
||||||
}
|
}
|
||||||
|
|
||||||
- (void)updateMask
|
- (void)updateLayers
|
||||||
{
|
{
|
||||||
if (!self.shapeLayer) {
|
if (!self.shapeLayer) {
|
||||||
self.shapeLayer = [CAShapeLayer new];
|
self.shapeLayer = [CAShapeLayer new];
|
||||||
|
@ -73,15 +97,21 @@ const CGFloat kBubbleTextVInset = 10.f;
|
||||||
self.layer.mask = self.maskLayer;
|
self.layer.mask = self.maskLayer;
|
||||||
}
|
}
|
||||||
|
|
||||||
UIBezierPath *bezierPath =
|
UIBezierPath *bezierPath = [self maskPath];
|
||||||
[self.class maskPathForSize:self.bounds.size isOutgoing:self.isOutgoing isRTL:self.isRTL];
|
|
||||||
|
|
||||||
self.shapeLayer.fillColor = self.bubbleColor.CGColor;
|
self.shapeLayer.fillColor = self.bubbleColor.CGColor;
|
||||||
|
// self.shapeLayer.bounds = self.bounds;
|
||||||
self.shapeLayer.path = bezierPath.CGPath;
|
self.shapeLayer.path = bezierPath.CGPath;
|
||||||
|
|
||||||
|
// self.maskLayer.bounds = self.bounds;
|
||||||
self.maskLayer.path = bezierPath.CGPath;
|
self.maskLayer.path = bezierPath.CGPath;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
- (UIBezierPath *)maskPath
|
||||||
|
{
|
||||||
|
return [self.class maskPathForSize:self.bounds.size isOutgoing:self.isOutgoing isRTL:self.isRTL];
|
||||||
|
}
|
||||||
|
|
||||||
+ (UIBezierPath *)maskPathForSize:(CGSize)size isOutgoing:(BOOL)isOutgoing isRTL:(BOOL)isRTL
|
+ (UIBezierPath *)maskPathForSize:(CGSize)size isOutgoing:(BOOL)isOutgoing isRTL:(BOOL)isRTL
|
||||||
{
|
{
|
||||||
UIBezierPath *bezierPath = [UIBezierPath new];
|
UIBezierPath *bezierPath = [UIBezierPath new];
|
||||||
|
|
|
@ -8,6 +8,7 @@
|
||||||
#import "ConversationViewItem.h"
|
#import "ConversationViewItem.h"
|
||||||
#import "NSAttributedString+OWS.h"
|
#import "NSAttributedString+OWS.h"
|
||||||
#import "OWSAudioMessageView.h"
|
#import "OWSAudioMessageView.h"
|
||||||
|
#import "OWSBubbleStrokeView.h"
|
||||||
#import "OWSBubbleView.h"
|
#import "OWSBubbleView.h"
|
||||||
#import "OWSExpirationTimerView.h"
|
#import "OWSExpirationTimerView.h"
|
||||||
#import "OWSGenericAttachmentView.h"
|
#import "OWSGenericAttachmentView.h"
|
||||||
|
@ -426,6 +427,22 @@ CG_INLINE CGSize CGSizeCeil(CGSize size)
|
||||||
}
|
}
|
||||||
lastSubview = bodyMediaView;
|
lastSubview = bodyMediaView;
|
||||||
bottomMargin = 0;
|
bottomMargin = 0;
|
||||||
|
|
||||||
|
BOOL shouldStrokeMediaView = [bodyMediaView isKindOfClass:[UIImageView class]];
|
||||||
|
if (shouldStrokeMediaView) {
|
||||||
|
OWSBubbleStrokeView *bubbleStrokeView = [OWSBubbleStrokeView new];
|
||||||
|
bubbleStrokeView.strokeThickness = 1.f;
|
||||||
|
bubbleStrokeView.strokeColor = [UIColor colorWithWhite:0.f alpha:0.1f];
|
||||||
|
bubbleStrokeView.bubbleView = self.bubbleView;
|
||||||
|
|
||||||
|
[self.bubbleView addSubview:bubbleStrokeView];
|
||||||
|
[bubbleStrokeView autoPinEdge:ALEdgeTop toEdge:ALEdgeTop ofView:bodyMediaView];
|
||||||
|
[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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
OWSMessageTextView *_Nullable bodyTextView = nil;
|
OWSMessageTextView *_Nullable bodyTextView = nil;
|
||||||
|
@ -1233,6 +1250,7 @@ CG_INLINE CGSize CGSizeCeil(CGSize size)
|
||||||
|
|
||||||
self.bubbleView.hidden = YES;
|
self.bubbleView.hidden = YES;
|
||||||
self.bubbleView.bubbleColor = nil;
|
self.bubbleView.bubbleColor = nil;
|
||||||
|
self.bubbleView.bubbleStrokeView = nil;
|
||||||
|
|
||||||
for (UIView *subview in self.bubbleView.subviews) {
|
for (UIView *subview in self.bubbleView.subviews) {
|
||||||
[subview removeFromSuperview];
|
[subview removeFromSuperview];
|
||||||
|
|
|
@ -703,6 +703,27 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
thread:thread];
|
thread:thread];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (DebugUIMessagesAction *)fakeOutgoingPngAction:(TSThread *)thread
|
||||||
|
actionLabel:(NSString *)actionLabel
|
||||||
|
imageSize:(CGSize)imageSize
|
||||||
|
backgroundColor:(UIColor *)backgroundColor
|
||||||
|
textColor:(UIColor *)textColor
|
||||||
|
imageLabel:(NSString *)imageLabel
|
||||||
|
messageState:(TSOutgoingMessageState)messageState
|
||||||
|
hasCaption:(BOOL)hasCaption
|
||||||
|
{
|
||||||
|
OWSAssert(thread);
|
||||||
|
|
||||||
|
return [self fakeOutgoingMediaAction:actionLabel
|
||||||
|
messageState:messageState
|
||||||
|
hasCaption:hasCaption
|
||||||
|
fakeAssetLoader:[DebugUIMessagesAssetLoader pngInstanceWithSize:imageSize
|
||||||
|
backgroundColor:backgroundColor
|
||||||
|
textColor:textColor
|
||||||
|
label:imageLabel]
|
||||||
|
thread:thread];
|
||||||
|
}
|
||||||
|
|
||||||
+ (DebugUIMessagesAction *)fakeOutgoingTinyPdfAction:(TSThread *)thread
|
+ (DebugUIMessagesAction *)fakeOutgoingTinyPdfAction:(TSThread *)thread
|
||||||
messageState:(TSOutgoingMessageState)messageState
|
messageState:(TSOutgoingMessageState)messageState
|
||||||
hasCaption:(BOOL)hasCaption
|
hasCaption:(BOOL)hasCaption
|
||||||
|
@ -1018,6 +1039,27 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
thread:thread];
|
thread:thread];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (DebugUIMessagesAction *)fakeIncomingPngAction:(TSThread *)thread
|
||||||
|
actionLabel:(NSString *)actionLabel
|
||||||
|
imageSize:(CGSize)imageSize
|
||||||
|
backgroundColor:(UIColor *)backgroundColor
|
||||||
|
textColor:(UIColor *)textColor
|
||||||
|
imageLabel:(NSString *)imageLabel
|
||||||
|
isAttachmentDownloaded:(BOOL)isAttachmentDownloaded
|
||||||
|
hasCaption:(BOOL)hasCaption
|
||||||
|
{
|
||||||
|
OWSAssert(thread);
|
||||||
|
|
||||||
|
return [self fakeIncomingMediaAction:actionLabel
|
||||||
|
isAttachmentDownloaded:isAttachmentDownloaded
|
||||||
|
hasCaption:hasCaption
|
||||||
|
fakeAssetLoader:[DebugUIMessagesAssetLoader pngInstanceWithSize:imageSize
|
||||||
|
backgroundColor:backgroundColor
|
||||||
|
textColor:textColor
|
||||||
|
label:imageLabel]
|
||||||
|
thread:thread];
|
||||||
|
}
|
||||||
|
|
||||||
+ (DebugUIMessagesAction *)fakeIncomingTinyPdfAction:(TSThread *)thread
|
+ (DebugUIMessagesAction *)fakeIncomingTinyPdfAction:(TSThread *)thread
|
||||||
isAttachmentDownloaded:(BOOL)isAttachmentDownloaded
|
isAttachmentDownloaded:(BOOL)isAttachmentDownloaded
|
||||||
hasCaption:(BOOL)hasCaption
|
hasCaption:(BOOL)hasCaption
|
||||||
|
@ -1338,6 +1380,112 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
[self fakeOutgoingTinyPngAction:thread messageState:TSOutgoingMessageStateSentToService hasCaption:NO],
|
[self fakeOutgoingTinyPngAction:thread messageState:TSOutgoingMessageStateSentToService hasCaption:NO],
|
||||||
[self fakeOutgoingTinyPngAction:thread messageState:TSOutgoingMessageStateSentToService hasCaption:YES],
|
[self fakeOutgoingTinyPngAction:thread messageState:TSOutgoingMessageStateSentToService hasCaption:YES],
|
||||||
]];
|
]];
|
||||||
|
if (includeLabels) {
|
||||||
|
[actions addObject:[self fakeOutgoingTextMessageAction:thread
|
||||||
|
messageState:TSOutgoingMessageStateSentToService
|
||||||
|
text:@"⚠️ Outgoing Reserved Color Png ⚠️"]];
|
||||||
|
}
|
||||||
|
[actions addObjectsFromArray:@[
|
||||||
|
[self fakeOutgoingPngAction:thread
|
||||||
|
actionLabel:@"Fake Outgoing White Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[UIColor whiteColor]
|
||||||
|
textColor:[UIColor ows_signalBrandBlueColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
messageState:TSOutgoingMessageStateUnsent
|
||||||
|
hasCaption:YES],
|
||||||
|
[self fakeOutgoingPngAction:thread
|
||||||
|
actionLabel:@"Fake Outgoing White Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[UIColor whiteColor]
|
||||||
|
textColor:[UIColor ows_signalBrandBlueColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
messageState:TSOutgoingMessageStateAttemptingOut
|
||||||
|
hasCaption:YES],
|
||||||
|
[self fakeOutgoingPngAction:thread
|
||||||
|
actionLabel:@"Fake Outgoing White Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[UIColor whiteColor]
|
||||||
|
textColor:[UIColor ows_signalBrandBlueColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
messageState:TSOutgoingMessageStateSentToService
|
||||||
|
hasCaption:YES],
|
||||||
|
|
||||||
|
[self fakeOutgoingPngAction:thread
|
||||||
|
actionLabel:@"Fake Outgoing 'Outgoing Unsent' Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingUnsent]
|
||||||
|
textColor:[UIColor whiteColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
messageState:TSOutgoingMessageStateUnsent
|
||||||
|
hasCaption:YES],
|
||||||
|
[self fakeOutgoingPngAction:thread
|
||||||
|
actionLabel:@"Fake Outgoing 'Outgoing Unsent' Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingUnsent]
|
||||||
|
textColor:[UIColor whiteColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
messageState:TSOutgoingMessageStateAttemptingOut
|
||||||
|
hasCaption:YES],
|
||||||
|
[self fakeOutgoingPngAction:thread
|
||||||
|
actionLabel:@"Fake Outgoing 'Outgoing Unsent' Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingUnsent]
|
||||||
|
textColor:[UIColor whiteColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
messageState:TSOutgoingMessageStateSentToService
|
||||||
|
hasCaption:YES],
|
||||||
|
|
||||||
|
[self fakeOutgoingPngAction:thread
|
||||||
|
actionLabel:@"Fake Outgoing 'Outgoing Sending' Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingSending]
|
||||||
|
textColor:[UIColor whiteColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
messageState:TSOutgoingMessageStateUnsent
|
||||||
|
hasCaption:YES],
|
||||||
|
[self fakeOutgoingPngAction:thread
|
||||||
|
actionLabel:@"Fake Outgoing 'Outgoing Sending' Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingSending]
|
||||||
|
textColor:[UIColor whiteColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
messageState:TSOutgoingMessageStateAttemptingOut
|
||||||
|
hasCaption:YES],
|
||||||
|
[self fakeOutgoingPngAction:thread
|
||||||
|
actionLabel:@"Fake Outgoing 'Outgoing Sending' Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingSending]
|
||||||
|
textColor:[UIColor whiteColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
messageState:TSOutgoingMessageStateSentToService
|
||||||
|
hasCaption:YES],
|
||||||
|
|
||||||
|
[self fakeOutgoingPngAction:thread
|
||||||
|
actionLabel:@"Fake Outgoing 'Outgoing Sent' Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingSent]
|
||||||
|
textColor:[UIColor whiteColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
messageState:TSOutgoingMessageStateUnsent
|
||||||
|
hasCaption:YES],
|
||||||
|
[self fakeOutgoingPngAction:thread
|
||||||
|
actionLabel:@"Fake Outgoing 'Outgoing Sent' Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingSent]
|
||||||
|
textColor:[UIColor whiteColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
messageState:TSOutgoingMessageStateAttemptingOut
|
||||||
|
hasCaption:YES],
|
||||||
|
[self fakeOutgoingPngAction:thread
|
||||||
|
actionLabel:@"Fake Outgoing 'Outgoing Sent' Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorOutgoingSent]
|
||||||
|
textColor:[UIColor whiteColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
messageState:TSOutgoingMessageStateSentToService
|
||||||
|
hasCaption:YES],
|
||||||
|
]];
|
||||||
if (includeLabels) {
|
if (includeLabels) {
|
||||||
[actions addObject:[self fakeOutgoingTextMessageAction:thread
|
[actions addObject:[self fakeOutgoingTextMessageAction:thread
|
||||||
messageState:TSOutgoingMessageStateSentToService
|
messageState:TSOutgoingMessageStateSentToService
|
||||||
|
@ -1476,6 +1624,44 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
[self fakeIncomingTinyPngAction:thread isAttachmentDownloaded:YES hasCaption:NO],
|
[self fakeIncomingTinyPngAction:thread isAttachmentDownloaded:YES hasCaption:NO],
|
||||||
[self fakeIncomingTinyPngAction:thread isAttachmentDownloaded:YES hasCaption:YES],
|
[self fakeIncomingTinyPngAction:thread isAttachmentDownloaded:YES hasCaption:YES],
|
||||||
]];
|
]];
|
||||||
|
if (includeLabels) {
|
||||||
|
[actions
|
||||||
|
addObject:[self fakeIncomingTextMessageAction:thread text:@"⚠️ Incoming Reserved Color Png ⚠️"]];
|
||||||
|
}
|
||||||
|
[actions addObjectsFromArray:@[
|
||||||
|
[self fakeIncomingPngAction:thread
|
||||||
|
actionLabel:@"Fake Incoming White Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[UIColor whiteColor]
|
||||||
|
textColor:[UIColor ows_signalBrandBlueColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
isAttachmentDownloaded:YES
|
||||||
|
hasCaption:YES],
|
||||||
|
[self fakeIncomingPngAction:thread
|
||||||
|
actionLabel:@"Fake Incoming White Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[UIColor whiteColor]
|
||||||
|
textColor:[UIColor ows_signalBrandBlueColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
isAttachmentDownloaded:NO
|
||||||
|
hasCaption:YES],
|
||||||
|
[self fakeIncomingPngAction:thread
|
||||||
|
actionLabel:@"Fake Incoming 'Incoming' Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorIncoming]
|
||||||
|
textColor:[UIColor whiteColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
isAttachmentDownloaded:YES
|
||||||
|
hasCaption:YES],
|
||||||
|
[self fakeIncomingPngAction:thread
|
||||||
|
actionLabel:@"Fake Incoming 'Incoming' Png"
|
||||||
|
imageSize:CGSizeMake(200.f, 200.f)
|
||||||
|
backgroundColor:[OWSMessagesBubbleImageFactory bubbleColorIncoming]
|
||||||
|
textColor:[UIColor whiteColor]
|
||||||
|
imageLabel:@"W"
|
||||||
|
isAttachmentDownloaded:NO
|
||||||
|
hasCaption:YES],
|
||||||
|
]];
|
||||||
if (includeLabels) {
|
if (includeLabels) {
|
||||||
[actions addObject:[self fakeIncomingTextMessageAction:thread text:@"⚠️ Incoming Tiny Pdf ⚠️"]];
|
[actions addObject:[self fakeIncomingTextMessageAction:thread text:@"⚠️ Incoming Tiny Pdf ⚠️"]];
|
||||||
}
|
}
|
||||||
|
@ -1519,7 +1705,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
{
|
{
|
||||||
OWSAssert(thread);
|
OWSAssert(thread);
|
||||||
|
|
||||||
return [DebugUIMessagesGroupAction allGroupActionWithLabel:@"Fake All Media"
|
return [DebugUIMessagesGroupAction allGroupActionWithLabel:@"All Fake Media"
|
||||||
subactions:[self allFakeMediaActions:thread includeLabels:YES]];
|
subactions:[self allFakeMediaActions:thread includeLabels:YES]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1527,7 +1713,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
{
|
{
|
||||||
OWSAssert(thread);
|
OWSAssert(thread);
|
||||||
|
|
||||||
return [DebugUIMessagesGroupAction randomGroupActionWithLabel:@"Fake Random Media"
|
return [DebugUIMessagesGroupAction randomGroupActionWithLabel:@"Random Fake Media"
|
||||||
subactions:[self allFakeMediaActions:thread includeLabels:NO]];
|
subactions:[self allFakeMediaActions:thread includeLabels:NO]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1744,7 +1930,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
{
|
{
|
||||||
OWSAssert(thread);
|
OWSAssert(thread);
|
||||||
|
|
||||||
return [DebugUIMessagesGroupAction allGroupActionWithLabel:@"Fake All Text"
|
return [DebugUIMessagesGroupAction allGroupActionWithLabel:@"All Fake Text"
|
||||||
subactions:[self allFakeTextActions:thread includeLabels:YES]];
|
subactions:[self allFakeTextActions:thread includeLabels:YES]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1752,7 +1938,7 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
{
|
{
|
||||||
OWSAssert(thread);
|
OWSAssert(thread);
|
||||||
|
|
||||||
return [DebugUIMessagesGroupAction randomGroupActionWithLabel:@"Fake Random Text"
|
return [DebugUIMessagesGroupAction randomGroupActionWithLabel:@"Random Fake Text"
|
||||||
subactions:[self allFakeTextActions:thread includeLabels:NO]];
|
subactions:[self allFakeTextActions:thread includeLabels:NO]];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -28,6 +28,10 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
+ (instancetype)wideLandscapePngInstance;
|
+ (instancetype)wideLandscapePngInstance;
|
||||||
+ (instancetype)largePngInstance;
|
+ (instancetype)largePngInstance;
|
||||||
+ (instancetype)tinyPngInstance;
|
+ (instancetype)tinyPngInstance;
|
||||||
|
+ (instancetype)pngInstanceWithSize:(CGSize)size
|
||||||
|
backgroundColor:(UIColor *)backgroundColor
|
||||||
|
textColor:(UIColor *)textColor
|
||||||
|
label:(NSString *)label;
|
||||||
+ (instancetype)tinyPdfInstance;
|
+ (instancetype)tinyPdfInstance;
|
||||||
+ (instancetype)largePdfInstance;
|
+ (instancetype)largePdfInstance;
|
||||||
+ (instancetype)missingPngInstance;
|
+ (instancetype)missingPngInstance;
|
||||||
|
|
|
@ -456,6 +456,17 @@ NS_ASSUME_NONNULL_BEGIN
|
||||||
return instance;
|
return instance;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
+ (instancetype)pngInstanceWithSize:(CGSize)size
|
||||||
|
backgroundColor:(UIColor *)backgroundColor
|
||||||
|
textColor:(UIColor *)textColor
|
||||||
|
label:(NSString *)label
|
||||||
|
{
|
||||||
|
return [DebugUIMessagesAssetLoader fakePngAssetLoaderWithImageSize:size
|
||||||
|
backgroundColor:backgroundColor
|
||||||
|
textColor:textColor
|
||||||
|
label:label];
|
||||||
|
}
|
||||||
|
|
||||||
+ (instancetype)tinyPdfInstance
|
+ (instancetype)tinyPdfInstance
|
||||||
{
|
{
|
||||||
static DebugUIMessagesAssetLoader *instance = nil;
|
static DebugUIMessagesAssetLoader *instance = nil;
|
||||||
|
|
|
@ -57,17 +57,25 @@ public class OWSMessagesBubbleImageFactory: NSObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static let bubbleColorIncoming = UIColor.jsq_messageBubbleLightGray()!
|
||||||
|
|
||||||
|
public static let bubbleColorOutgoingUnsent = UIColor.gray
|
||||||
|
|
||||||
|
public static let bubbleColorOutgoingSending = UIColor.ows_fadedBlue
|
||||||
|
|
||||||
|
public static let bubbleColorOutgoingSent = UIColor.ows_materialBlue
|
||||||
|
|
||||||
public func bubbleColor(message: TSMessage) -> UIColor {
|
public func bubbleColor(message: TSMessage) -> UIColor {
|
||||||
if message is TSIncomingMessage {
|
if message is TSIncomingMessage {
|
||||||
return UIColor.jsq_messageBubbleLightGray()!
|
return OWSMessagesBubbleImageFactory.bubbleColorIncoming
|
||||||
} else if let outgoingMessage = message as? TSOutgoingMessage {
|
} else if let outgoingMessage = message as? TSOutgoingMessage {
|
||||||
switch outgoingMessage.messageState {
|
switch outgoingMessage.messageState {
|
||||||
case .unsent:
|
case .unsent:
|
||||||
return UIColor.gray
|
return OWSMessagesBubbleImageFactory.bubbleColorOutgoingUnsent
|
||||||
case .attemptingOut:
|
case .attemptingOut:
|
||||||
return UIColor.ows_fadedBlue
|
return OWSMessagesBubbleImageFactory.bubbleColorOutgoingSending
|
||||||
default:
|
default:
|
||||||
return UIColor.ows_materialBlue
|
return OWSMessagesBubbleImageFactory.bubbleColorOutgoingSent
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
owsFail("Unexpected message type: \(message)")
|
owsFail("Unexpected message type: \(message)")
|
||||||
|
|
Loading…
Reference in a new issue