Merge branch 'charlesmchen/tweakQuotedReplies2'

pull/1/head
Matthew Chen 7 years ago
commit 600b1aa49f

@ -22,19 +22,29 @@ class OWSLayerView: UIView {
override var bounds: CGRect {
didSet {
layoutCallback(self)
updateLayer()
}
}
override var frame: CGRect {
didSet {
layoutCallback(self)
updateLayer()
}
}
override var center: CGPoint {
didSet {
layoutCallback(self)
updateLayer()
}
}
private func updateLayer() {
// Prevent the shape layer from animating changes.
CATransaction.begin()
CATransaction.setDisableActions(true)
layoutCallback(self)
CATransaction.commit()
}
}

@ -267,9 +267,16 @@ NS_ASSUME_NONNULL_BEGIN
if (self.isQuotedReply) {
// Flush any pending "text" subviews.
[self insertAnyTextViewsIntoStackView:textViews];
BOOL isFirstSubview = ![self insertAnyTextViewsIntoStackView:textViews];
[textViews removeAllObjects];
if (isFirstSubview) {
UIView *spacerView = [UIView containerView];
[spacerView autoSetDimension:ALDimensionHeight toSize:self.quotedReplyTopMargin];
[spacerView setCompressionResistanceHigh];
[self.stackView addArrangedSubview:spacerView];
}
BOOL isOutgoing = [self.viewItem.interaction isKindOfClass:TSOutgoingMessage.class];
DisplayableText *_Nullable displayableQuotedText
= (self.viewItem.hasQuotedText ? self.viewItem.displayableQuotedText : nil);
@ -287,8 +294,6 @@ NS_ASSUME_NONNULL_BEGIN
OWSAssert(quotedMessageSize);
[self.viewConstraints addObject:[quotedMessageView autoSetDimension:ALDimensionHeight
toSize:quotedMessageSize.CGSizeValue.height]];
[self.bubbleView addPartnerView:quotedMessageView.boundsStrokeView];
}
UIView *_Nullable bodyMediaView = nil;
@ -342,6 +347,13 @@ NS_ASSUME_NONNULL_BEGIN
[self insertAnyTextViewsIntoStackView:textViews];
[textViews removeAllObjects];
if (self.isQuotedReply) {
UIView *spacerView = [UIView containerView];
[spacerView autoSetDimension:ALDimensionHeight toSize:self.bodyMediaQuotedReplyVSpacing];
[spacerView setCompressionResistanceHigh];
[self.stackView addArrangedSubview:spacerView];
}
if (self.hasBodyMediaWithThumbnail) {
// The "body media" view casts a shadow "downward" onto adjacent views,
@ -533,10 +545,10 @@ NS_ASSUME_NONNULL_BEGIN
return !self.viewItem.shouldHideFooter && !shouldFooterOverlayMedia;
}
- (void)insertAnyTextViewsIntoStackView:(NSArray<UIView *> *)textViews
- (BOOL)insertAnyTextViewsIntoStackView:(NSArray<UIView *> *)textViews
{
if (textViews.count < 1) {
return;
return NO;
}
UIStackView *textStackView = [[UIStackView alloc] initWithArrangedSubviews:textViews];
@ -549,6 +561,7 @@ NS_ASSUME_NONNULL_BEGIN
self.conversationStyle.textInsetBottom,
self.conversationStyle.textInsetHorizontal);
[self.stackView addArrangedSubview:textStackView];
return YES;
}
// We now eagerly create our view hierarchy (to do this exactly once per cell usage)
@ -593,6 +606,16 @@ NS_ASSUME_NONNULL_BEGIN
return 2.f;
}
- (CGFloat)bodyMediaQuotedReplyVSpacing
{
return 8.f;
}
- (CGFloat)quotedReplyTopMargin
{
return 7.f;
}
#pragma mark - Load / Unload
- (void)loadContent
@ -1126,6 +1149,9 @@ NS_ASSUME_NONNULL_BEGIN
NSValue *_Nullable quotedMessageSize = [self quotedMessageSize];
if (quotedMessageSize) {
if (!senderNameSize) {
cellSize.height += self.quotedReplyTopMargin;
}
cellSize.width = MAX(cellSize.width, quotedMessageSize.CGSizeValue.width);
cellSize.height += quotedMessageSize.CGSizeValue.height;
}
@ -1148,6 +1174,10 @@ NS_ASSUME_NONNULL_BEGIN
cellSize.height += groupSize.height;
[textViewSizes removeAllObjects];
}
if (bodyMediaSize && quotedMessageSize && self.hasFullWidthMediaView) {
cellSize.height += self.bodyMediaQuotedReplyVSpacing;
}
}
NSValue *_Nullable bodyTextSize = [self bodyTextSize];

@ -20,7 +20,6 @@ NS_ASSUME_NONNULL_BEGIN
@interface OWSQuotedMessageView : UIView
@property (nonatomic, nullable, readonly) OWSBubbleShapeView *boundsStrokeView;
@property (nonatomic, nullable, weak) id<OWSQuotedMessageViewDelegate> delegate;
- (instancetype)init NS_UNAVAILABLE;

@ -23,7 +23,6 @@ NS_ASSUME_NONNULL_BEGIN
@property (nonatomic, nullable, readonly) DisplayableText *displayableQuotedText;
@property (nonatomic, readonly) ConversationStyle *conversationStyle;
@property (nonatomic, nullable) OWSBubbleShapeView *boundsStrokeView;
@property (nonatomic, readonly) BOOL isForPreview;
@property (nonatomic, readonly) BOOL isOutgoing;
@ -116,34 +115,108 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark -
- (CGFloat)bubbleHMargin
{
return 6.f;
}
- (CGFloat)hSpacing
{
return 8.f;
}
- (CGFloat)stripeThickness
{
return 4.f;
}
- (void)createContents
{
// Ensure only called once.
OWSAssert(!self.boundsStrokeView);
OWSAssert(self.subviews.count < 1);
self.backgroundColor = [UIColor whiteColor];
self.userInteractionEnabled = YES;
self.layoutMargins = UIEdgeInsetsZero;
self.clipsToBounds = YES;
self.boundsStrokeView = [OWSBubbleShapeView new];
self.boundsStrokeView.strokeColor = [self.conversationStyle primaryColor];
self.boundsStrokeView.strokeThickness = 1.f;
[self addSubview:self.boundsStrokeView];
[self.boundsStrokeView autoPinToSuperviewEdges];
[self.boundsStrokeView setContentHuggingLow];
[self.boundsStrokeView setCompressionResistanceLow];
CAShapeLayer *maskLayer = [CAShapeLayer new];
OWSLayerView *innerBubbleView = [[OWSLayerView alloc]
initWithFrame:CGRectZero
layoutCallback:^(UIView *layerView) {
CGRect layerFrame = layerView.bounds;
UIBezierPath *bezierPath = [UIBezierPath new];
CGFloat bubbleLeft = 0.f;
CGFloat bubbleRight = layerFrame.size.width;
CGFloat bubbleTop = 0.f;
CGFloat bubbleBottom = layerFrame.size.height;
// TODO:
CGFloat bubbleTopRounding = 12.f;
CGFloat bubbleBottomRounding = 12.f;
[bezierPath moveToPoint:CGPointMake(bubbleLeft + bubbleTopRounding, bubbleTop)];
[bezierPath addLineToPoint:CGPointMake(bubbleRight - bubbleTopRounding, bubbleTop)];
[bezierPath addQuadCurveToPoint:CGPointMake(bubbleRight, bubbleTop + bubbleTopRounding)
controlPoint:CGPointMake(bubbleRight, bubbleTop)];
[bezierPath addLineToPoint:CGPointMake(bubbleRight, bubbleBottom - bubbleBottomRounding)];
[bezierPath addQuadCurveToPoint:CGPointMake(bubbleRight - bubbleBottomRounding, bubbleBottom)
controlPoint:CGPointMake(bubbleRight, bubbleBottom)];
[bezierPath addLineToPoint:CGPointMake(bubbleLeft + bubbleBottomRounding, bubbleBottom)];
[bezierPath addQuadCurveToPoint:CGPointMake(bubbleLeft, bubbleBottom - bubbleBottomRounding)
controlPoint:CGPointMake(bubbleLeft, bubbleBottom)];
[bezierPath addLineToPoint:CGPointMake(bubbleLeft, bubbleTop + bubbleTopRounding)];
[bezierPath addQuadCurveToPoint:CGPointMake(bubbleLeft + bubbleTopRounding, bubbleTop)
controlPoint:CGPointMake(bubbleLeft, bubbleTop)];
maskLayer.path = bezierPath.CGPath;
}];
innerBubbleView.layer.mask = maskLayer;
// TODO: Color.
innerBubbleView.backgroundColor = [[UIColor ows_cyan800Color] colorWithAlphaComponent:0.25f];
[self addSubview:innerBubbleView];
[innerBubbleView autoPinLeadingToSuperviewMarginWithInset:self.bubbleHMargin];
[innerBubbleView autoPinTrailingToSuperviewMarginWithInset:self.bubbleHMargin];
[innerBubbleView autoPinTopToSuperviewMargin];
[innerBubbleView autoPinBottomToSuperviewMargin];
UIStackView *hStackView = [UIStackView new];
hStackView.axis = UILayoutConstraintAxisHorizontal;
hStackView.spacing = self.hSpacing;
[innerBubbleView addSubview:hStackView];
[hStackView autoPinToSuperviewEdges];
UIView *stripeView = [UIView new];
// TODO: Color.
stripeView.backgroundColor = [UIColor ows_cyan800Color];
[stripeView autoSetDimension:ALDimensionWidth toSize:self.stripeThickness];
[stripeView setContentHuggingHigh];
[stripeView setCompressionResistanceHigh];
[hStackView addArrangedSubview:stripeView];
UIStackView *vStackView = [UIStackView new];
vStackView.axis = UILayoutConstraintAxisVertical;
vStackView.layoutMargins = UIEdgeInsetsMake(self.textVMargin, 0, self.textVMargin, 0);
vStackView.layoutMarginsRelativeArrangement = YES;
[hStackView addArrangedSubview:vStackView];
UILabel *quotedAuthorLabel = [self configureQuotedAuthorLabel];
[vStackView addArrangedSubview:quotedAuthorLabel];
[quotedAuthorLabel autoSetDimension:ALDimensionHeight toSize:self.quotedAuthorHeight];
[quotedAuthorLabel setContentHuggingVerticalHigh];
[quotedAuthorLabel setContentHuggingHorizontalLow];
[quotedAuthorLabel setCompressionResistanceHorizontalLow];
UILabel *quotedTextLabel = [self configureQuotedTextLabel];
[vStackView addArrangedSubview:quotedTextLabel];
[quotedTextLabel setContentHuggingLow];
[quotedTextLabel setCompressionResistanceLow];
UIView *_Nullable quotedAttachmentView = nil;
if (self.hasQuotedAttachment) {
UIView *_Nullable quotedAttachmentView = nil;
UIImage *_Nullable thumbnailImage = [self tryToLoadThumbnailImage];
if (thumbnailImage) {
quotedAttachmentView = [self imageViewForImage:thumbnailImage];
// Stroke the edge softly.
quotedAttachmentView.layer.borderColor = [UIColor colorWithWhite:0.f alpha:0.1f].CGColor;
quotedAttachmentView.layer.borderWidth = 1.f;
quotedAttachmentView.layer.cornerRadius = 2.f;
quotedAttachmentView.clipsToBounds = YES;
quotedAttachmentView.backgroundColor = [UIColor whiteColor];
@ -154,8 +227,6 @@ NS_ASSUME_NONNULL_BEGIN
contentImageView.tintColor = [UIColor whiteColor];
[quotedAttachmentView addSubview:contentImageView];
[contentImageView autoCenterInSuperview];
[contentImageView setContentHuggingHigh];
[contentImageView setCompressionResistanceHigh];
}
} else if (self.quotedMessage.thumbnailDownloadFailed) {
// TODO design review icon and color
@ -163,105 +234,43 @@ NS_ASSUME_NONNULL_BEGIN
[[UIImage imageNamed:@"btnRefresh--white"] imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImageView *contentImageView = [self imageViewForImage:contentIcon];
contentImageView.contentMode = UIViewContentModeScaleAspectFit;
contentImageView.userInteractionEnabled = YES;
contentImageView.tintColor = UIColor.whiteColor;
quotedAttachmentView = [UIView containerView];
[quotedAttachmentView addSubview:contentImageView];
quotedAttachmentView.backgroundColor = self.highlightColor;
quotedAttachmentView.layer.cornerRadius = self.quotedAttachmentSize * 0.5f;
[contentImageView autoCenterInSuperview];
[contentImageView
autoSetDimensionsToSize:CGSizeMake(self.quotedAttachmentSize * 0.5f, self.quotedAttachmentSize * 0.5f)];
contentImageView.layer.minificationFilter = kCAFilterTrilinear;
contentImageView.layer.magnificationFilter = kCAFilterTrilinear;
UITapGestureRecognizer *tapGesture =
[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(didTapFailedThumbnailDownload:)];
[quotedAttachmentView addGestureRecognizer:tapGesture];
quotedAttachmentView.userInteractionEnabled = YES;
} else {
quotedAttachmentView = [UIView containerView];
quotedAttachmentView.backgroundColor = self.highlightColor;
quotedAttachmentView.layer.cornerRadius = self.quotedAttachmentSize * 0.5f;
// TODO: Use new icons.
UIImage *contentIcon =
[UIImage imageNamed:(self.isAudioAttachment ? @"attachment_audio" : @"attachment_file")];
contentIcon = [contentIcon imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate];
UIImage *contentIcon = [UIImage imageNamed:@"generic-attachment"];
UIImageView *contentImageView = [self imageViewForImage:contentIcon];
contentImageView.tintColor = [UIColor whiteColor];
[quotedAttachmentView addSubview:contentImageView];
contentImageView.contentMode = UIViewContentModeScaleAspectFit;
UIView *wrapper = [UIView containerView];
[wrapper addSubview:contentImageView];
[contentImageView autoCenterInSuperview];
[contentImageView setContentHuggingHigh];
[contentImageView setCompressionResistanceHigh];
[contentImageView autoSetDimension:ALDimensionWidth toSize:self.quotedAttachmentSize * 0.5f];
quotedAttachmentView = wrapper;
}
quotedAttachmentView.userInteractionEnabled = YES;
[self addSubview:quotedAttachmentView];
[quotedAttachmentView autoPinTrailingToSuperviewMarginWithInset:self.quotedContentHInset];
[quotedAttachmentView autoVCenterInSuperview];
[quotedAttachmentView autoSetDimension:ALDimensionWidth toSize:self.quotedAttachmentSize];
[quotedAttachmentView autoSetDimension:ALDimensionHeight toSize:self.quotedAttachmentSize];
[quotedAttachmentView setContentHuggingHigh];
[quotedAttachmentView setCompressionResistanceHigh];
}
UILabel *quotedAuthorLabel = [self configureQuotedAuthorLabel];
{
[self addSubview:quotedAuthorLabel];
[quotedAuthorLabel autoPinEdgeToSuperviewEdge:ALEdgeTop withInset:self.quotedAuthorTopInset];
[quotedAuthorLabel autoPinLeadingToSuperviewMarginWithInset:self.quotedContentHInset];
if (quotedAttachmentView) {
[quotedAuthorLabel autoPinTrailingToLeadingEdgeOfView:quotedAttachmentView
offset:self.quotedAttachmentHSpacing];
} else {
[quotedAuthorLabel autoPinTrailingToSuperviewMarginWithInset:self.quotedContentHInset];
}
[quotedAuthorLabel autoSetDimension:ALDimensionHeight toSize:self.quotedAuthorHeight];
[quotedAuthorLabel setContentHuggingLow];
[quotedAuthorLabel setCompressionResistanceLow];
}
{
// Stripe and text container.
UIView *stripeAndTextContainer = [UIView containerView];
[self addSubview:stripeAndTextContainer];
[stripeAndTextContainer autoPinEdge:ALEdgeTop
toEdge:ALEdgeBottom
ofView:quotedAuthorLabel
withOffset:self.quotedAuthorBottomSpacing];
[stripeAndTextContainer autoPinLeadingToSuperviewMarginWithInset:self.quotedContentHInset];
if (quotedAttachmentView) {
[stripeAndTextContainer autoPinTrailingToLeadingEdgeOfView:quotedAttachmentView
offset:self.quotedAttachmentHSpacing];
} else {
[stripeAndTextContainer autoPinTrailingToSuperviewMarginWithInset:self.quotedContentHInset];
}
[stripeAndTextContainer autoPinBottomToSuperviewMarginWithInset:self.quotedTextBottomInset];
[stripeAndTextContainer setContentHuggingLow];
[stripeAndTextContainer setCompressionResistanceLow];
// Stripe.
UIView *quoteStripView = [UIView containerView];
quoteStripView.backgroundColor = self.highlightColor;
quoteStripView.userInteractionEnabled = NO;
quoteStripView.layer.cornerRadius = self.quotedReplyStripeRounding;
[stripeAndTextContainer addSubview:quoteStripView];
[quoteStripView autoPinHeightToSuperview];
[quoteStripView autoPinLeadingToSuperviewMargin];
[quoteStripView autoSetDimension:ALDimensionWidth toSize:self.quotedReplyStripeThickness];
[quoteStripView setContentHuggingVerticalLow];
[quoteStripView setContentHuggingHorizontalHigh];
[quoteStripView setCompressionResistanceHigh];
// Text.
UILabel *quotedTextLabel = [self configureQuotedTextLabel];
[stripeAndTextContainer addSubview:quotedTextLabel];
[quotedTextLabel autoPinTopToSuperviewMarginWithInset:self.quotedReplyStripeVExtension];
[quotedTextLabel autoPinBottomToSuperviewMarginWithInset:self.quotedReplyStripeVExtension];
[quotedTextLabel autoPinLeadingToTrailingEdgeOfView:quoteStripView offset:self.quotedReplyStripeHSpacing];
[quotedTextLabel autoPinTrailingToSuperviewMargin];
[quotedTextLabel setContentHuggingLow];
[quotedTextLabel setCompressionResistanceLow];
[hStackView addArrangedSubview:quotedAttachmentView];
} else {
// If there's no attachment, add an empty view so that
// the stack view's spacing serves as a margin between
// the text views and the trailing edge.
UIView *emptyView = [UIView containerView];
[hStackView addArrangedSubview:emptyView];
[emptyView setContentHuggingHigh];
[emptyView autoSetDimension:ALDimensionWidth toSize:0.f];
}
}
@ -341,7 +350,7 @@ NS_ASSUME_NONNULL_BEGIN
font = self.fileTypeFont;
}
self.quotedTextLabel.numberOfLines = self.isForPreview ? 1 : 3;
self.quotedTextLabel.numberOfLines = self.isForPreview ? 1 : 2;
self.quotedTextLabel.lineBreakMode = NSLineBreakByTruncatingTail;
self.quotedTextLabel.text = text;
self.quotedTextLabel.textColor = textColor;
@ -423,6 +432,7 @@ NS_ASSUME_NONNULL_BEGIN
self.quotedAuthorLabel.text = quotedAuthorText;
self.quotedAuthorLabel.font = self.quotedAuthorFont;
// TODO:
self.quotedAuthorLabel.textColor = [self quotedAuthorColor];
self.quotedAuthorLabel.lineBreakMode = NSLineBreakByTruncatingTail;
self.quotedAuthorLabel.numberOfLines = 1;
@ -432,78 +442,63 @@ NS_ASSUME_NONNULL_BEGIN
#pragma mark - Measurement
- (CGFloat)textVMargin
{
return 7.f;
}
- (CGSize)sizeForMaxWidth:(CGFloat)maxWidth
{
CGSize result = CGSizeZero;
result.width += self.quotedContentHInset;
result.width += self.bubbleHMargin * 2 + self.stripeThickness + self.hSpacing * 2;
CGFloat thumbnailHeight = 0.f;
if (self.hasQuotedAttachment) {
result.width += self.quotedAttachmentHSpacing;
result.width += self.quotedAttachmentSize;
thumbnailHeight += self.quotedAttachmentMinVInset;
thumbnailHeight += self.quotedAttachmentSize;
thumbnailHeight += self.quotedAttachmentMinVInset;
}
result.width += self.quotedContentHInset;
// Quoted Author
CGFloat quotedAuthorWidth = 0.f;
CGFloat textWidth = 0.f;
CGFloat maxTextWidth = maxWidth - result.width;
CGFloat textHeight = self.textVMargin * 2 + self.quotedAuthorHeight;
{
CGFloat maxQuotedAuthorWidth = maxWidth - result.width;
UILabel *quotedAuthorLabel = [self configureQuotedAuthorLabel];
CGSize quotedAuthorSize
= CGSizeCeil([quotedAuthorLabel sizeThatFits:CGSizeMake(maxQuotedAuthorWidth, CGFLOAT_MAX)]);
quotedAuthorSize.width = MIN(quotedAuthorSize.width, maxQuotedAuthorWidth);
quotedAuthorWidth = quotedAuthorSize.width;
result.height += self.quotedAuthorTopInset;
result.height += self.quotedAuthorHeight;
result.height += self.quotedAuthorBottomSpacing;
CGSize quotedAuthorSize = CGSizeCeil([quotedAuthorLabel sizeThatFits:CGSizeMake(maxTextWidth, CGFLOAT_MAX)]);
textWidth = quotedAuthorSize.width;
}
CGFloat quotedTextWidth = 0.f;
{
CGFloat maxQuotedTextWidth
= (maxWidth - (result.width + self.quotedReplyStripeThickness + self.quotedReplyStripeHSpacing));
UILabel *quotedTextLabel = [self configureQuotedTextLabel];
CGSize textSize = CGSizeCeil([quotedTextLabel sizeThatFits:CGSizeMake(maxQuotedTextWidth, CGFLOAT_MAX)]);
textSize.width = MIN(textSize.width, maxQuotedTextWidth);
quotedTextWidth = textSize.width + self.quotedReplyStripeThickness + self.quotedReplyStripeHSpacing;
result.height += textSize.height + self.quotedReplyStripeVExtension * 2;
CGSize textSize = CGSizeCeil([quotedTextLabel sizeThatFits:CGSizeMake(maxTextWidth, CGFLOAT_MAX)]);
textWidth = MAX(textWidth, textSize.width);
textHeight += textSize.height;
}
CGFloat textWidth = MAX(quotedAuthorWidth, quotedTextWidth);
textWidth = MIN(textWidth, maxTextWidth);
result.width += textWidth;
result.height += MAX(textHeight, thumbnailHeight);
result.height += self.quotedTextBottomInset;
result.height = MAX(result.height, thumbnailHeight);
return result;
return CGSizeCeil(result);
}
- (UIFont *)quotedAuthorFont
{
return UIFont.ows_dynamicTypeCaption1Font.ows_mediumWeight;
return UIFont.ows_dynamicTypeSubheadlineFont.ows_mediumWeight;
}
- (UIColor *)quotedAuthorColor
{
return [UIColor colorWithRGBHex:0x8E8E93];
return [UIColor ows_light90Color];
}
- (UIColor *)quotedTextColor
{
return [UIColor blackColor];
return [UIColor ows_light90Color];
}
- (UIFont *)quotedTextFont
@ -536,63 +531,9 @@ NS_ASSUME_NONNULL_BEGIN
return (CGFloat)ceil([self quotedAuthorFont].lineHeight * 1.f);
}
- (CGFloat)quotedAuthorTopInset
{
return 8.f;
}
- (CGFloat)quotedAuthorBottomSpacing
{
return 3.f;
}
- (CGFloat)quotedTextBottomInset
{
return 8.f;
}
- (CGFloat)quotedReplyStripeThickness
{
return 2.f;
}
- (CGFloat)quotedReplyStripeVExtension
{
return 4.f;
}
- (CGFloat)quotedReplyStripeRounding
{
return 1.f;
}
// The spacing between the vertical "quoted reply stripe"
// and the quoted message content.
- (CGFloat)quotedReplyStripeHSpacing
{
return 4.f;
}
// Distance from top edge of "quoted message" bubble to top of message bubble.
- (CGFloat)quotedAttachmentMinVInset
{
return 12.f;
}
- (CGFloat)quotedAttachmentSize
{
return 44.f;
}
- (CGFloat)quotedAttachmentHSpacing
{
return 8.f;
}
// Distance from sides of the quoted content to the sides of the message bubble.
- (CGFloat)quotedContentHInset
{
return 8.f;
return 54.f;
}
#pragma mark -

@ -159,4 +159,24 @@ public class MessageRecipientStatusUtils: NSObject {
referenceView: referenceView)
return status
}
@objc
public class func description(forMessageReceiptStatus value: MessageReceiptStatus) -> String {
switch(value) {
case .read:
return "read"
case .uploading:
return "uploading"
case .delivered:
return "delivered"
case .sent:
return "sent"
case .sending:
return "sending"
case .failed:
return "failed"
case .skipped:
return "skipped"
}
}
}

Loading…
Cancel
Save