From 19699fd45f6a3e961071db93f4f07975fd18ccba Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Thu, 5 Jul 2018 10:25:30 -0400 Subject: [PATCH] Tweak message send failed indicator. --- .../Contents.json | 6 +- .../error-20@1x.png | Bin 0 -> 365 bytes .../error-20@2x.png | Bin 0 -> 765 bytes .../error-20@3x.png | Bin 0 -> 1380 bytes .../message_send_failure@1x.png | Bin 1733 -> 0 bytes .../message_send_failure@2x.png | Bin 2428 -> 0 bytes .../message_send_failure@3x.png | Bin 3328 -> 0 bytes .../ConversationView/Cells/OWSMessageCell.m | 80 ++++++++++++++++-- SignalMessaging/categories/UIColor+OWS.m | 2 +- 9 files changed, 77 insertions(+), 11 deletions(-) rename Signal/Images.xcassets/{message_send_failure.imageset => message_send_failed.imageset}/Contents.json (64%) create mode 100644 Signal/Images.xcassets/message_send_failed.imageset/error-20@1x.png create mode 100644 Signal/Images.xcassets/message_send_failed.imageset/error-20@2x.png create mode 100644 Signal/Images.xcassets/message_send_failed.imageset/error-20@3x.png delete mode 100644 Signal/Images.xcassets/message_send_failure.imageset/message_send_failure@1x.png delete mode 100644 Signal/Images.xcassets/message_send_failure.imageset/message_send_failure@2x.png delete mode 100644 Signal/Images.xcassets/message_send_failure.imageset/message_send_failure@3x.png diff --git a/Signal/Images.xcassets/message_send_failure.imageset/Contents.json b/Signal/Images.xcassets/message_send_failed.imageset/Contents.json similarity index 64% rename from Signal/Images.xcassets/message_send_failure.imageset/Contents.json rename to Signal/Images.xcassets/message_send_failed.imageset/Contents.json index c1ca74cf9..6bd09fe32 100644 --- a/Signal/Images.xcassets/message_send_failure.imageset/Contents.json +++ b/Signal/Images.xcassets/message_send_failed.imageset/Contents.json @@ -2,17 +2,17 @@ "images" : [ { "idiom" : "universal", - "filename" : "message_send_failure@1x.png", + "filename" : "error-20@1x.png", "scale" : "1x" }, { "idiom" : "universal", - "filename" : "message_send_failure@2x.png", + "filename" : "error-20@2x.png", "scale" : "2x" }, { "idiom" : "universal", - "filename" : "message_send_failure@3x.png", + "filename" : "error-20@3x.png", "scale" : "3x" } ], diff --git a/Signal/Images.xcassets/message_send_failed.imageset/error-20@1x.png b/Signal/Images.xcassets/message_send_failed.imageset/error-20@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..d385cefade3cd9370484ef8c604545f0e8e4fdeb GIT binary patch literal 365 zcmV-z0h0cSP)Px$CrLy>R5%f>l`(F@Fc?NrD=rbyTjUTO!@%D2pf2SONaYGl;RKzL*jgbvv$uWE zvLgYppfR8HP_V!Mi*fvi(WqZzhG(#ZEgU0WJLa68n>59>gI_qn3SJ{#JLa4oy;(gl zGY8Ed@C=Tf%Q5Hl=(VQL*M+@dc!X=xqc??~_+7da8vd&kYDSQo>wfqXaw}_@lRjBv ztr_7#`NUkE`;t@3gydwc88bJtfp1vDP+4n6V_*#}{J>CIyMfxk3cjFJp9ECB=cgpu zz&%V#LSpSx%nH4E;7iGBtu@0w4~>59*u3DAoVsJ9;qC|9(2~|$Q1377TF*e0-Zb`R zt_6cJe(2F_n6(#jV^io|USH`BF5O1=&OW(!81#aru9FXH&|knGjmlU^uSijZ00000 LNkvXXu0mjfCT^q0 literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/message_send_failed.imageset/error-20@2x.png b/Signal/Images.xcassets/message_send_failed.imageset/error-20@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..391b7f3bc8f1cad3ab4abff9286b414c62ec7bb9 GIT binary patch literal 765 zcmVPx%w@E}nR9FesnY~KHKoo_eHj09sh3$fs-M+xS!D4S`YvlvTve=1_VWFU4qxcY_ zu(gnC1zQ!Y)bqu?;Tqj#X33uij+rEL&pkUcnaRY3WPWrM+84XxrlX3<*zr!~EAdgR z92?3o6i4D`B#9vwjnc6y#Y6E$j5SuQj|N(3mVzCrJc-3buex?A?uk8dOI(|fa!=$Q zb*Nj6M-%P2v7ktP>4)gW?{$vwvKR{L5<{%lLYo}qio%L&pNU>9)%mU%Ev6U)v1p{C z*CrP^gMi4n=mlJUb}KrMem`DL0&cuwY*eX zvMERJVY6tEH{qt?J^T-YO}E&r{GW93k0zZ}yQX{onRsfu!EwRMGFkH{7L@kn(u(2{hwACq)Ba}{GXX2mJ}^PBSL zz>NPSViPG#(uKGu_QWlb{Vb&16S+qnzkFFdnrN2-rXX6A9ls@*_lO2sXqFCE9F`!z vc83}zhFCO$G0&Q7;=F0}#jaS{zahQ=L)bKMt?Ijr00000NkvXXu0mjfd4p^` literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/message_send_failed.imageset/error-20@3x.png b/Signal/Images.xcassets/message_send_failed.imageset/error-20@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..35a740157fc7186c0bb146d79a56d300f43dcaf7 GIT binary patch literal 1380 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 diff --git a/Signal/Images.xcassets/message_send_failure.imageset/message_send_failure@2x.png b/Signal/Images.xcassets/message_send_failure.imageset/message_send_failure@2x.png deleted file mode 100644 index 1e540f14b570f59e90ccd819849bbccbc0294b7d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2428 zcmZ`*3pkr+8xB?792!H5Iz<@PpPW=hM4X}ym9W$yYC0hw4N1PpflRfORh^2qTC_FH zYK(NuU+qduhG~mhf0xd-`q7iNL_>95%U}Bv*5-HVcU@oJ_r0I{exK)lzVH36~LLA6JF_>U1fD&_f5E}*~iV4t^0|*%iF^A0+5XA0CC4&IX6)+l! zP*Q|R?npW%1mOen0faMZ2MU8EX(12@BA*#gppkd2%Au7za=%c>BcRc#si~+`Clts} zKx189UC|gE8i#X)7>!yQx`&RgWMT!}`m1N2$u6QFVDksnY0mv39S`fx%2}wAj($HG?T}M__J|Kt32Lu90 zMsi-2sA6mR^ml1UP8iIpLKR)B2q5X{2)Lbym5CFch+e}{sX!6&;R6gI z$PWcUHc9D%qgW!GP%bM<)%dEEh*q2c(;Lx<5q?LNL{+?mSFO!w{-m!X}(#_Jw==_MZ z+O24ZtcgvHxj_}JNbkyK)2U-z*&SV%q(+Y4K*Y(qyw2q$+KETg9UPWmqH3yRifFk^ zga-F1y!o_!Wo2beI%&LYFg|sn?hjeYOQfK`zu%~mI#u=KXR}%3&pI(KE=EyF#@|MF zx3#sQvOJ2$4q;$zThbpKFYqKCJhC${5>qs2kGD9s>-*9L=ca82HU{n%#Z!6~aDDrr zN4CeupD!7dSHFQ*1l^uxvsiQ1?OlTlvW?jbFXxHbX11-*`tHwlvc^m9aY4|-P)Bph zt4QaNj>S){zviT7*c+x9F4iL8byDq}GmVWWE>81=I$8YJVFsP3X8ShyG-2#NqqRwBZ;IE!I zK8Qa;wb6gwwroXBSLwg&y7)%!-5cm-L$N*J z+|x!1I6DWQU>?NvQcRYPS4)M2gCp@8E_u=`O=aQfsQl{FWhr`^luswViEbsnpROOL#0eI`H9VJIXxdvRpc=AoL{p?Tn3DlK_F`3_Q+*Bkpke@aOE$C=Wn z9{BiQ1H8tytH$e>H&@w7c5chbEGoV9{p}|?71B76aX-zIDj8Id*y`7i(3KVp688K% z)7fZWNm(Y>@)}B@{v3YMj%nIdQ0X8z{vla$7kp%GdgXVh3^KPbEJ`BQ}!0 zd(6Hox7d!1$glZ19@v&uNR zo}HlNF4#ZnX)?Y^E-@_>T+zm18bYOc|D8!b_qfL+HeI^sN#c25pZw0DhX!U-`OjXT zy5$_cgeRy=eVOVV-FG|s>(E9Svli((**YX)b`4NJNgTN}S}z|08GY8@4ynsVsB=q> z^9kW^K53qKkv2?p!&MZ*TaLY{ysq|u^g7krfLM$ef0XOydzFE;r7w_eQ<^vY$LsUU zrn!ZIhCNMZx@*w8LqxeBTM4yXZ_1X-8bY7)z54t|ZRtNivL3azEtuB@0hH=0YhHK5&!@I diff --git a/Signal/Images.xcassets/message_send_failure.imageset/message_send_failure@3x.png b/Signal/Images.xcassets/message_send_failure.imageset/message_send_failure@3x.png deleted file mode 100644 index 1413112271cb83876f42503962b73a17f5704404..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3328 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 IVj?sD2i78S`2YX_ diff --git a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m index b6e43c341..9f0ced321 100644 --- a/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m +++ b/Signal/src/ViewControllers/ConversationView/Cells/OWSMessageCell.m @@ -20,12 +20,15 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic) UIView *dateStrokeView; @property (nonatomic) UILabel *dateHeaderLabel; @property (nonatomic) AvatarImageView *avatarView; +@property (nonatomic, nullable) UIImageView *sendFailureBadgeView; @property (nonatomic, nullable) NSMutableArray *viewConstraints; @property (nonatomic) BOOL isPresentingMenuController; @end +#pragma mark - + @implementation OWSMessageCell // `[UIView init]` invokes `[self initWithFrame:...]`. @@ -131,6 +134,15 @@ NS_ASSUME_NONNULL_BEGIN return self.viewItem.interaction.interactionType == OWSInteractionType_OutgoingMessage; } +- (BOOL)shouldHavesendFailureBadge +{ + if (![self.viewItem.interaction isKindOfClass:[TSOutgoingMessage class]]) { + return NO; + } + TSOutgoingMessage *outgoingMessage = (TSOutgoingMessage *)self.viewItem.interaction; + return outgoingMessage.messageState == TSOutgoingMessageStateFailed; +} + #pragma mark - Load - (void)loadForDisplayWithTransaction:(YapDatabaseReadTransaction *)transaction @@ -158,13 +170,42 @@ NS_ASSUME_NONNULL_BEGIN relation:NSLayoutRelationGreaterThanOrEqual], ]]; } else { - [self.viewConstraints addObjectsFromArray:@[ - [self.messageBubbleView autoPinEdgeToSuperviewEdge:ALEdgeLeading - withInset:self.conversationStyle.gutterLeading - relation:NSLayoutRelationGreaterThanOrEqual], - [self.messageBubbleView autoPinEdgeToSuperviewEdge:ALEdgeTrailing - withInset:self.conversationStyle.gutterTrailing], - ]]; + if (self.shouldHavesendFailureBadge) { + self.sendFailureBadgeView = [UIImageView new]; + self.sendFailureBadgeView.image = + [self.sendFailureBadge imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; + self.sendFailureBadgeView.tintColor = [UIColor ows_destructiveRedColor]; + [self.contentView addSubview:self.sendFailureBadgeView]; + + CGFloat sendFailureBadgeBottomMargin + = round(self.conversationStyle.lastTextLineAxis - self.sendFailureBadgeSize * 0.5f); + [self.viewConstraints addObjectsFromArray:@[ + [self.messageBubbleView autoPinEdgeToSuperviewEdge:ALEdgeLeading + withInset:self.conversationStyle.gutterLeading + relation:NSLayoutRelationGreaterThanOrEqual], + [self.sendFailureBadgeView autoPinLeadingToTrailingEdgeOfView:self.messageBubbleView + offset:self.sendFailureBadgeSpacing], + // V-align the "send failure" badge with the + // last line of the text (if any, or where it + // would be). + [self.messageBubbleView autoPinEdge:ALEdgeBottom + toEdge:ALEdgeBottom + ofView:self.sendFailureBadgeView + withOffset:sendFailureBadgeBottomMargin], + [self.sendFailureBadgeView autoPinEdgeToSuperviewEdge:ALEdgeTrailing + withInset:self.conversationStyle.gutterTrailing], + [self.sendFailureBadgeView autoSetDimension:ALDimensionWidth toSize:self.sendFailureBadgeSize], + [self.sendFailureBadgeView autoSetDimension:ALDimensionHeight toSize:self.sendFailureBadgeSize], + ]]; + } else { + [self.viewConstraints addObjectsFromArray:@[ + [self.messageBubbleView autoPinEdgeToSuperviewEdge:ALEdgeLeading + withInset:self.conversationStyle.gutterLeading + relation:NSLayoutRelationGreaterThanOrEqual], + [self.messageBubbleView autoPinEdgeToSuperviewEdge:ALEdgeTrailing + withInset:self.conversationStyle.gutterTrailing], + ]]; + } } [self updateDateHeader]; @@ -184,6 +225,24 @@ NS_ASSUME_NONNULL_BEGIN } } +- (UIImage *)sendFailureBadge +{ + UIImage *image = [UIImage imageNamed:@"message_send_failed"]; + OWSAssert(image); + OWSAssert(image.size.width == self.sendFailureBadgeSize && image.size.height == self.sendFailureBadgeSize); + return image; +} + +- (CGFloat)sendFailureBadgeSize +{ + return 20.f; +} + +- (CGFloat)sendFailureBadgeSpacing +{ + return 8.f; +} + // * If cell is visible, lazy-load (expensive) view contents. // * If cell is not visible, eagerly unload view contents. - (void)ensureMediaLoadState @@ -362,6 +421,10 @@ NS_ASSUME_NONNULL_BEGIN cellSize.height += self.dateHeaderHeight; + if (self.shouldHavesendFailureBadge) { + cellSize.width += self.sendFailureBadgeSize + self.sendFailureBadgeSpacing; + } + cellSize = CGSizeCeil(cellSize); return cellSize; @@ -404,6 +467,9 @@ NS_ASSUME_NONNULL_BEGIN self.avatarView.image = nil; [self.avatarView removeFromSuperview]; + [self.sendFailureBadgeView removeFromSuperview]; + self.sendFailureBadgeView = nil; + [self hideMenuControllerIfNecessary]; [[NSNotificationCenter defaultCenter] removeObserver:self]; diff --git a/SignalMessaging/categories/UIColor+OWS.m b/SignalMessaging/categories/UIColor+OWS.m index d8447eb65..4b73dc74b 100644 --- a/SignalMessaging/categories/UIColor+OWS.m +++ b/SignalMessaging/categories/UIColor+OWS.m @@ -79,7 +79,7 @@ NS_ASSUME_NONNULL_BEGIN + (UIColor *)ows_destructiveRedColor { - return [UIColor colorWithRed:0.98639106750488281 green:0.10408364236354828 blue:0.33135244250297546 alpha:1.f]; + return [UIColor colorWithRed:255.f / 255.f green:38.f / 255.f blue:31.f / 255.f alpha:1.0f]; } + (UIColor *)ows_errorMessageBorderColor