From ae7934c1174bf7e7dc9b94870cb1a830e68fe7d8 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 28 Apr 2017 18:00:24 -0400 Subject: [PATCH] Update appearance of audio and generic attachment adapters. // FREEBIE --- .../Contents.json | 23 ++ .../pause_black_40@1x.png | Bin 0 -> 1880 bytes .../pause_black_40@2x.png | Bin 0 -> 2902 bytes .../pause_black_40@3x.png | Bin 0 -> 3974 bytes .../Contents.json | 23 ++ .../audio_pause_white_40@1x.png | Bin 0 -> 1955 bytes .../audio_pause_white_40@2x.png | Bin 0 -> 3026 bytes .../audio_pause_white_40@3x.png | Bin 0 -> 4172 bytes .../Contents.json | 23 ++ .../play_black_40@1x.png | Bin 0 -> 1874 bytes .../play_black_40@2x.png | Bin 0 -> 2911 bytes .../play_black_40@3x.png | Bin 0 -> 3996 bytes .../Contents.json | 23 ++ .../play_white_40@1x.png | Bin 0 -> 1966 bytes .../play_white_40@2x.png | Bin 0 -> 3059 bytes .../play_white_40@3x.png | Bin 0 -> 4282 bytes .../TSGenericAttachmentAdapter.m | 22 +- .../TSVideoAttachmentAdapter.m | 216 +++++++++++++----- .../AttachmentApprovalViewController.swift | 2 +- .../OWSAudioAttachmentPlayer.h | 1 + .../OWSAudioAttachmentPlayer.m | 17 ++ .../src/ViewControllers/ViewControllerUtils.m | 17 +- 22 files changed, 285 insertions(+), 82 deletions(-) create mode 100644 Signal/Images.xcassets/audio_pause_black_40.imageset/Contents.json create mode 100644 Signal/Images.xcassets/audio_pause_black_40.imageset/pause_black_40@1x.png create mode 100644 Signal/Images.xcassets/audio_pause_black_40.imageset/pause_black_40@2x.png create mode 100644 Signal/Images.xcassets/audio_pause_black_40.imageset/pause_black_40@3x.png create mode 100644 Signal/Images.xcassets/audio_pause_white_40.imageset/Contents.json create mode 100644 Signal/Images.xcassets/audio_pause_white_40.imageset/audio_pause_white_40@1x.png create mode 100644 Signal/Images.xcassets/audio_pause_white_40.imageset/audio_pause_white_40@2x.png create mode 100644 Signal/Images.xcassets/audio_pause_white_40.imageset/audio_pause_white_40@3x.png create mode 100644 Signal/Images.xcassets/audio_play_black_40.imageset/Contents.json create mode 100644 Signal/Images.xcassets/audio_play_black_40.imageset/play_black_40@1x.png create mode 100644 Signal/Images.xcassets/audio_play_black_40.imageset/play_black_40@2x.png create mode 100644 Signal/Images.xcassets/audio_play_black_40.imageset/play_black_40@3x.png create mode 100644 Signal/Images.xcassets/audio_play_white_40.imageset/Contents.json create mode 100644 Signal/Images.xcassets/audio_play_white_40.imageset/play_white_40@1x.png create mode 100644 Signal/Images.xcassets/audio_play_white_40.imageset/play_white_40@2x.png create mode 100644 Signal/Images.xcassets/audio_play_white_40.imageset/play_white_40@3x.png diff --git a/Signal/Images.xcassets/audio_pause_black_40.imageset/Contents.json b/Signal/Images.xcassets/audio_pause_black_40.imageset/Contents.json new file mode 100644 index 000000000..08698f7cf --- /dev/null +++ b/Signal/Images.xcassets/audio_pause_black_40.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "pause_black_40@1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "pause_black_40@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "pause_black_40@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Signal/Images.xcassets/audio_pause_black_40.imageset/pause_black_40@1x.png b/Signal/Images.xcassets/audio_pause_black_40.imageset/pause_black_40@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..ce91744d91284be654b36ac7ae8f20a1b175749a GIT binary patch literal 1880 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 OcHNwIVu~I1CjJX!!KV}e literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/audio_pause_black_40.imageset/pause_black_40@3x.png b/Signal/Images.xcassets/audio_pause_black_40.imageset/pause_black_40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..d52379c0179519936267aba920aa84aac5ab2a22 GIT binary patch literal 3974 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 xOcJkn#cKH7n1g6_0_gwSME!lvI6;>1s;*b z3=G`DAk4@xYmNj^jZ$VvL`j6Nk5zJhu3lnFep0GlMQ#C5H3Nf9g%yyQn_7~nP?4LH zS8P>bs{~eI1!RMS^_3LBN=mYAl_Got6rA&mQWZ?~O!N$t?6?#Z6l{u8(yW49+@RWl zJX@uVl9B=|ef{$Ca=mh6z5JqdeM3u2OML?)eIp}XpbFjM%Dj@q3f;V7Wr!g#b6ir3 zlZ!G7N;32F6hP)CCgqow*eWT3EP?}wJ4-Ut5H{r%L%jv`pgu@O-%!s$ADgz+icB2Z zKr%SBr6j|BRZv=#1NKu&vVLk#YHn&?Nik5LAy(^vVGGxY;>e1`0*GbcK!o_s2IO+9 zpw#00oKjE_gyvGs1{@~boCJkYwXNnb|4F) zYw$111o|`)x zocyBTg2d!hki)=Qkc7}xgRP0gWet)9lE#!|tK!n6tkmQZq}T$+8941bC8p~m3ESvn zRc!-I30A)ODVb@NE{P?nc18w<=2iwKRz?;I5Qc@hjXs(hBo}~WoQqNuOY)0C^7C`- zz`n=@aTSd9%pf|E<)K<_^g+1@DOW+VELaqnXYIIvI$`ZJFk~FE!vz!TH^b zPcYnRD*eIcpUCBRSa3pohVE_Ahz8$)z9ROjOB#oiKgiS_l6i40P3lPBq1qP>CT>Qm zX}nGaJogSt#hjWoy+^s6>6XIUjZ5}lNN>ry&?K56BJ^?6g%yXjC#0P%ej2Z2z@h(u z`O0VQ7UK(-=6Anq+roZ0P;!mReU{#C$wS4h3oQRd&y?CJq&wq@;*Ey(H1BgiN`AlB zWb>Ojzx49WFGoA>xz+sIwDQ=5r)l#%XEo+#9GUdtY*TM!_u+!$J!iVp{LlS(wSm>x zbAGK|0(ZUILxuUv6FdJi<=&qjA^*)z`*_=ayToHpdcH|*Q=L&}I$3dQLbHqM0~wp< zEf4>5cdxb1Wcm@}yjAMM^$yb&EWJ0&(X zo6DqDeYIO6on0{Xfz}*;)u}nbKozo=dQESrMfk??saBeC-tJiYw|(2uUz@X5gxxm3 zWpzWrzrr@=dEzAXn!8QRpTo~Tv!C$ytGj;M@k^QhNps3g%YOvhPso|wx-&w-@RrV< zR`v;ZbTX6`;&oN`|44IO)N#8k+a_$u3fZ^Z3knynXp`E)yV`8}(z(h@SpV-!yqe!O zA#d@v=eL$E|7)AJOW;yL)TN$#|9q0fS|-TODtR!|p!#0qPKDl2e7@IM7VXltGAeVh zej51st(o?vNEuW&kdY{C(n QKv1>m>FVdQ&MBb@07-)59RL6T literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/audio_pause_white_40.imageset/audio_pause_white_40@2x.png b/Signal/Images.xcassets/audio_pause_white_40.imageset/audio_pause_white_40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..5acbc3c35a63f2c52d435d0b25b2efae2615d28d GIT binary patch literal 3026 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 literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/audio_play_black_40.imageset/Contents.json b/Signal/Images.xcassets/audio_play_black_40.imageset/Contents.json new file mode 100644 index 000000000..2f22c2c65 --- /dev/null +++ b/Signal/Images.xcassets/audio_play_black_40.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "play_black_40@1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "play_black_40@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "play_black_40@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Signal/Images.xcassets/audio_play_black_40.imageset/play_black_40@1x.png b/Signal/Images.xcassets/audio_play_black_40.imageset/play_black_40@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..435dd73db6d849f85a3a84711f385de4a3f22f02 GIT binary patch literal 1874 zcmeAS@N?(olHy`uVBq!ia0vp^8X(NU1|)m_?Z^dEjKx9jP7LeL$-D$|I14-?iy0WW zg+Z8+Vb&Z81_llpi<;HsXMd|v6mX?-X(Gs7c7{+3kj2o|M`E)8SrADBDCn&MGAmMZB3v?o0SfkoiGhtiRta>C&iOg{ zMZpD$$*CZRfwdqBp{oX46N$?jBnc#qDalsFrAb+-$t6g!1&lLr+ILD!*GCez(Z{OV z2AC48eDhN>(<)sOOH%EO3=GY64NP>6EJ6&;tqe@8%z;NR|bQ0`sgL7f>fG|J!lxuFc6~U|>4w>Eaj? z!TENEfA$pziT3SbtOxDYx#e!H3*|rhJ|K6m*w>V!>lLE9-S;=SAKl!M^p_*ZrfTCN zQ7?VbZTG^s9xc?$y868FOrrCoxhcZ_KMy)@GJZcl(dcv9rn!Er%h+y7YRqZecChy8!B&QH`nSbh6VHTSJomv`_@OqBff zfj90zsRjG-19czoZBwn_t6tE*@0^}(9Y}q*L;0MMx&4xXptJ6BS@mg;% zaC%Z%Q=Oobd~K2Eq8$(H9mL(PnlPFjm~l+bv;AXSvwy;aT~Cz1WlG$ZnOZ9C?|tOx zDZx*&&tDjAv($R261V%qib>^jCeJ=A^Gs{4b;X~Cyq4#-IesoTmioq+-9H$!)THmL z^@ejtPc*$bv|lE9&Zfwx+jpLk)Xlz=zv05M7us&?)U%%iZ}2$&N~-OdR&cm=xbX7L z6C)2X$S(P@YB#rg!VH-i>yK(jwy|%L%6xrD{DrgV&KK_wYws{oX|Oy~TGesaVS9Un zu7$;gS^t%7n-kUc{`w(zc%@8v@r>8LVfFWT(r$+37Ef4rHtOlNa#`8lo>}J2>p#Xz z2ptAGI5g{yir$?YbEnEJc%8-Sc2DKVi7Cv*ZzGtJMA%*|u3_4^`~Hoor_NaPiJcEs zb~$mgj=x)QTc&XFjMHrH%W!7D~j@!G=c2ys4EM?!kGU;;A-eX43q$q$R8pV;p> r#rU-vFcnRk9QKxHi}8gcJb##jJeIw9rE7f+RMC05`njxgN@xNA+=#`= literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/audio_play_black_40.imageset/play_black_40@2x.png b/Signal/Images.xcassets/audio_play_black_40.imageset/play_black_40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..1ff1429e1f7c2e63ef1039bc10ad5276e2350780 GIT binary patch literal 2911 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 bXAaoSS+o30%jZ^0Pz~zo>gTe~DWM4fX*$)! literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/audio_play_white_40.imageset/play_white_40@2x.png b/Signal/Images.xcassets/audio_play_white_40.imageset/play_white_40@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..2b414d83a223f104b97a09d5f7839cd89753b7f4 GIT binary patch literal 3059 zcmZ`*3pkW%8y@F#Xh@AivuX`H%^_#QjD&VE1`%TtGZ$Z=#2YbK^7zn000#1 zey}+#xH}6kX-UEVS>^dM!A+cEP!t-a1b3C2Pgp$%TAu!GUs zct>ZjHJwQY8^I0XNNtQP7!0;x`Ujv6+Z_5V7tGMwfowJdg+N3^M8G2q;B+PhvER(h z41v@~=YgiluhEmLRot@7WuM{4VmS~q%zo4dMH@9F3Fc3&PHo%3yuEyZRE+O z2K?(3%KBWEpg@E$g4hp7BEBXgbEy9z6Gr}1=I{4URg7?E$a+oweh6|1nMMv}vjn>R zU$qnT_8;N@CCMQ%Hq6$WxKW#hFmu#lGK(G(E^NV(P%0avZ?Rs`R`}nJY^bd1GzOE* zVhLmzqtBAf*j7INUmJ|c7mv;0R)G_fDyWns%nP&sv%zL;E8p{L2Ajc60%7Y>&QuOL z1aCtXG<3ZRQ=|prtAVXTYkCNs>B=Dak%ft^OEy7U+3Pl*|7Ei&uu16ehhl~M29f>P zn|4dEXY0@YK@tVA3AR9dm2Dw-5>SqGe`-La4T(+0=p*-=ppb?reN*tpz)-LWTR59C z5Js$-WD=XsbfeQlFzZ#&gj28q+;~H|IsRE{fe@aeO{Z$($gZP;GmDWGD8HP4jO--` zk{19VMX|H7a^r|h^Lzr`$r=sWnGR39JTG^2?eurK39|XNH|-q3e*5KPr&UjW+H-HV z;C|-?Vw_qy@V$2Cm~Bh0oQn=QeoWg#*?puX6Kfoot_w`A6Q-}9C|6zc4rcm058Y^5k!;)QI6s_q8RrCQpA;$!D@ zAP}{%>w0{hp8F()Moip0lKdf3QF-}{M^7K@j_Bc=lZ_|z_MMXA8{?%r4IP=Ub|b~b zS`=4w$LxBV26Vm5LlTr{$@86J)1DqTdwhDYXq`J6drKit%LFpS;l(VL##?by+|d*A zr428|7XP?nguufGw{pzGZj+sZkp_CN%L<)Aj|c}criz%zf!NV@|E4K z5gMm%>IL)`d(}j3=V-2OBY%LcAYvsI5I^5g=SMDsuIt@4?BL2|TmXvSd0axIrDapz z{9484bK%$H#fXjsLR->gC*q(vX(un6Q|?$0me_nP1OSm+jBf>XyWB@ zmUZ1EW33ksx)m2=qiPMP+RbDrJf=O>Qshk5T@Yx8^={Mi&wW*utu&D{Ds8oj z9-{;^pa$$cQOeZSX$n~~bSE(_z;q&`^;b@U`eI9w$nza8Sy$d)(?~y}yDZP6Rzb1N za%xhvi9{|BPoOrxOLd$L-7^BYt#-;*jkfztGC!@gKRfx5cvYObA@0`0eQMtriQ8WL z^Hx9XEHkjI&T;yp62o{(l0xsAf#pJ#%U5hDFUZFO?4`RTM&rk#%=R_zt0_4Un4>tO z<#LxD$voDr5Zkdb^>~gw3{B!@SaikRdKgkPASY9)@=DTWsa;2_es)gMD>wXV;?<+- zj-ibi=XE&kMsb1q9o@;8f;Uq>rlN@WkyU+z!7?ezQC9_QhNS5Zo0WtvhZ}XxKCw*^zV1Xvf!LstuRV z(qr8MB8JrZ{7*AedMn@~`fnw1i^^jWY1E0nqe{_7pn1M87PJ;YUIv9Nply7o?6=S~ zy$1Eddx@^%=!IHiMs!+<_h_Ny949A=zhn8_-rQJd%wGIk=&DB4PyOO)wgDpFbZN_;zm%ubh{=VPzQJ=ldS+@=jbQS1&BCp=VYstLFo z7L@GS>crE+x4MXI!{xov#7kIGiXk|W>Sw=u1}Qci`)Oy{jAT(+eCxsyQ&EBw@bwgB zR4cr_jd4wl`o*KO@C5T=vlMksMj>-CIK}xxVIN>6>`zN* zQk_S&3tsVwiS>6*pEBe+7F^1GeLoPDp5b&j++Awsyc(Q?J>8eg z`K>fqQG9SwX&f_!Tc*?7M|n1wo9Atx zx-zd>uQ(T!<9udtZO}}-()Dl1AFqG?``ORAYeea)7l!Rz>>$~s_=df53&xF*TN9-g zU0Yxiy__@|U(=0tJ7+4|(~uRl*VLqZtbm7@ChiWNSov-oBw{qwD>WJ1e&$k6#C+pw z-MzMN7-}`enpvMN<$7n0b20;NI+$zOLD~$xWv+V%s;SXPoMn}LQ}0EJm;6APVO$kz@`L7{N=ucFcunVp z=qInP*?zcCpV%hZHiqp1BF@?uX^OmLbm$fIizM8yPXFbA`pXPE7OP+==2(i-!;-+~ z&n_q7FXiaMz>cqqs{1`wy+49=KiXcwoVfU6!BwNK4bV1-jXzXT8~AqnIpj@rSlXw) z9l22BAL0$D(11CtvbnO^luA49r~wRZYWIq`OG(oqm(E}_o4&=#=fm<4{rHvi z?C`XnQpkXne0`-343-FNY7>dOkTL^&>QmDt+o1-YpHB?BHw>NC8|YFw3Oc+}c%(gZ z*>td%2s!EK)Bf6KC`bEF7K0fFebobquVav*~q6>R}Q(gW8K-i%V8KUz(Jw-}e zGc>9m3>r4F9sJkEPr6gaee>#m?`v-zEGEx3k6BlpiF<{SQ-t^Qr&< literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/audio_play_white_40.imageset/play_white_40@3x.png b/Signal/Images.xcassets/audio_play_white_40.imageset/play_white_40@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..073333aaa91be54524774c9e7bcc5598329ff005 GIT binary patch literal 4282 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 O6HE;)krl^LasLA_wmy~s literal 0 HcmV?d00001 diff --git a/Signal/src/Models/TSMessageAdapaters/TSGenericAttachmentAdapter.m b/Signal/src/Models/TSMessageAdapaters/TSGenericAttachmentAdapter.m index 95315bf20..af6bdc0aa 100644 --- a/Signal/src/Models/TSMessageAdapaters/TSGenericAttachmentAdapter.m +++ b/Signal/src/Models/TSMessageAdapaters/TSGenericAttachmentAdapter.m @@ -78,7 +78,7 @@ NS_ASSUME_NONNULL_BEGIN - (CGFloat)bubbleHeight { - return 45.f; + return 35.f; } - (CGFloat)iconSize @@ -86,11 +86,6 @@ NS_ASSUME_NONNULL_BEGIN return 40.f; } -- (CGFloat)hMargin -{ - return 10.f; -} - - (CGFloat)vMargin { return 10.f; @@ -100,7 +95,7 @@ NS_ASSUME_NONNULL_BEGIN { if (_cachedMediaView == nil) { CGSize viewSize = [self mediaViewDisplaySize]; - UIColor *textColor = (self.incoming ? [UIColor blackColor] : [UIColor whiteColor]); + UIColor *textColor = (self.incoming ? [UIColor colorWithWhite:0.2 alpha:1.f] : [UIColor whiteColor]); _cachedMediaView = [[UIView alloc] initWithFrame:CGRectMake(0.f, 0.f, viewSize.width, viewSize.height)]; @@ -112,8 +107,8 @@ NS_ASSUME_NONNULL_BEGIN const CGFloat kBubbleTailWidth = 6.f; CGRect contentFrame = CGRectMake(self.incoming ? kBubbleTailWidth : 0.f, self.vMargin, - viewSize.width - kBubbleTailWidth - 10, - viewSize.height - self.vMargin * 2.f); + viewSize.width - kBubbleTailWidth - (self.incoming ? 10 : 15), + viewSize.height - self.vMargin * 2); UIImage *image = [UIImage imageNamed:(self.incoming ? @"file-black-40" : @"file-white-40")]; OWSAssert(image); @@ -125,7 +120,10 @@ NS_ASSUME_NONNULL_BEGIN imageView.frame = iconFrame; [_cachedMediaView addSubview:imageView]; - NSString *fileExtension = [MIMETypeUtil fileExtensionForMIMEType:self.attachment.contentType]; + NSString *fileExtension = self.attachment.filePath.pathExtension; + if (fileExtension.length < 1) { + [MIMETypeUtil fileExtensionForMIMEType:self.attachment.contentType]; + } if (fileExtension.length < 1) { fileExtension = NSLocalizedString(@"GENERIC_ATTACHMENT_DEFAULT_TYPE", @"A default label for attachment whose file extension cannot be determined."); @@ -164,7 +162,7 @@ NS_ASSUME_NONNULL_BEGIN topLabel.text = topText; topLabel.textColor = textColor; topLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; - topLabel.font = [UIFont ows_mediumFontWithSize:15.f]; + topLabel.font = [UIFont ows_regularFontWithSize:ScaleFromIPhone5To7Plus(13.f, 15.f)]; [topLabel sizeToFit]; [_cachedMediaView addSubview:topLabel]; @@ -177,7 +175,7 @@ NS_ASSUME_NONNULL_BEGIN bottomLabel.text = bottomText; bottomLabel.textColor = [textColor colorWithAlphaComponent:0.85f]; bottomLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; - bottomLabel.font = [UIFont ows_regularFontWithSize:13.f]; + bottomLabel.font = [UIFont ows_regularFontWithSize:ScaleFromIPhone5To7Plus(11.f, 13.f)]; [bottomLabel sizeToFit]; [_cachedMediaView addSubview:bottomLabel]; diff --git a/Signal/src/Models/TSMessageAdapaters/TSVideoAttachmentAdapter.m b/Signal/src/Models/TSMessageAdapaters/TSVideoAttachmentAdapter.m index ea23568f7..a9d3a07a2 100644 --- a/Signal/src/Models/TSMessageAdapaters/TSVideoAttachmentAdapter.m +++ b/Signal/src/Models/TSMessageAdapaters/TSVideoAttachmentAdapter.m @@ -9,31 +9,29 @@ #import "TSAttachmentStream.h" #import "TSMessagesManager.h" #import "TSStorageManager+keyingMaterial.h" +#import "UIColor+JSQMessages.h" #import "UIColor+OWS.h" #import "UIFont+OWS.h" #import "UIView+OWS.h" +#import "ViewControllerUtils.h" #import #import #import -const CGFloat kAudioViewWidth = 100; -const CGFloat kAudioButtonHeight = kAudioViewWidth; -const CGFloat kAudioViewVSpacing = 5; -const CGFloat kAudioLabelHeight = 20; -const CGFloat kAudioBottomMargin = 5; - NS_ASSUME_NONNULL_BEGIN @interface TSVideoAttachmentAdapter () @property (nonatomic) UIImage *image; -@property (nonatomic, nullable) UIImageView *cachedImageView; +@property (nonatomic, nullable) UIView *cachedMediaView; @property (nonatomic) TSAttachmentStream *attachment; @property (nonatomic, nullable) UIButton *audioPlayPauseButton; -@property (nonatomic, nullable) UILabel *audioLabel; +@property (nonatomic, nullable) UILabel *audioBottomLabel; @property (nonatomic) BOOL incoming; @property (nonatomic, nullable) AttachmentUploadView *attachmentUploadView; @property (nonatomic) BOOL isAudioPlaying; +@property (nonatomic) CGFloat audioProgressSeconds; +@property (nonatomic) CGFloat audioDurationSeconds; @property (nonatomic) BOOL isPaused; // See comments on OWSMessageMediaAdapter. @@ -50,7 +48,7 @@ NS_ASSUME_NONNULL_BEGIN if (self) { _image = attachment.image; - _cachedImageView = nil; + _cachedMediaView = nil; _attachmentId = attachment.uniqueId; _contentType = attachment.contentType; _attachment = attachment; @@ -61,8 +59,8 @@ NS_ASSUME_NONNULL_BEGIN - (void)clearAllViews { - [_cachedImageView removeFromSuperview]; - _cachedImageView = nil; + [_cachedMediaView removeFromSuperview]; + _cachedMediaView = nil; _attachmentUploadView = nil; } @@ -86,35 +84,97 @@ NS_ASSUME_NONNULL_BEGIN return [MIMETypeUtil isSupportedVideoMIMEType:_contentType]; } +- (void)setAudioProgress:(CGFloat)progress duration:(CGFloat)duration +{ + OWSAssert([NSThread isMainThread]); + + self.audioProgressSeconds = progress; + self.audioDurationSeconds = duration; + + [self updateAudioBottomLabel]; +} + +- (NSString *)formatTime:(long)timeSeconds +{ + long seconds = timeSeconds % 60; + long minutes = (timeSeconds / 60) % 60; + long hours = timeSeconds / 3600; + + if (hours > 0) { + return [NSString stringWithFormat:@"%ld:%02ld:%02ld", hours, minutes, seconds]; + } else { + return [NSString stringWithFormat:@"%ld:%02ld", minutes, seconds]; + } +} + +- (void)updateAudioBottomLabel +{ + if (self.isAudioPlaying && self.audioProgressSeconds > 0 && self.audioDurationSeconds > 0) { + self.audioBottomLabel.text = [NSString stringWithFormat:@"%@ / %@", + [self formatTime:(long)round(self.audioProgressSeconds)], + [self formatTime:(long)round(self.audioDurationSeconds)]]; + } else { + NSError *error; + unsigned long long fileSize = + [[NSFileManager defaultManager] attributesOfItemAtPath:self.attachment.filePath error:&error].fileSize; + OWSAssert(!error); + NSString *bottomText = [ViewControllerUtils formatFileSize:fileSize]; + self.audioBottomLabel.text = bottomText; + } +} + +- (void)setAudioIcon:(UIImage *)image +{ + [_audioPlayPauseButton setImage:image forState:UIControlStateNormal]; + [_audioPlayPauseButton setImage:image forState:UIControlStateDisabled]; + _audioPlayPauseButton.layer.opacity = 0.8f; +} + - (void)setAudioIconToPlay { - [_audioPlayPauseButton - setImage:[UIImage imageNamed:(_incoming ? @"audio_play_blue_bubble" : @"audio_play_white_bubble")] - forState:UIControlStateNormal]; + [self setAudioIcon:[UIImage imageNamed:(self.incoming ? @"audio_play_black_40" : @"audio_play_white_40")]]; } - (void)setAudioIconToPause { - [_audioPlayPauseButton - setImage:[UIImage imageNamed:(_incoming ? @"audio_pause_blue_bubble" : @"audio_pause_white_bubble")] - forState:UIControlStateNormal]; + [self setAudioIcon:[UIImage imageNamed:(self.incoming ? @"audio_pause_black_40" : @"audio_pause_white_40")]]; } #pragma mark - JSQMessageMediaData protocol +- (CGFloat)bubbleHeight +{ + return 35.f; +} + +- (CGFloat)iconSize +{ + return 40.f; +} + +- (CGFloat)vMargin +{ + return 10.f; +} + +- (UIColor *)audioTextColor +{ + return (self.incoming ? [UIColor colorWithWhite:0.2 alpha:1.f] : [UIColor whiteColor]); +} + - (UIView *)mediaView { CGSize size = [self mediaViewDisplaySize]; if ([self isVideo]) { - if (self.cachedImageView == nil) { + if (self.cachedMediaView == nil) { UIImageView *imageView = [[UIImageView alloc] initWithImage:self.image]; imageView.contentMode = UIViewContentModeScaleAspectFill; imageView.frame = CGRectMake(0.0f, 0.0f, size.width, size.height); imageView.clipsToBounds = YES; [JSQMessagesMediaViewBubbleImageMasker applyBubbleImageMaskToMediaView:imageView isOutgoing:self.appliesMediaViewMaskAsOutgoing]; - self.cachedImageView = imageView; + self.cachedMediaView = imageView; UIImage *img = [UIImage imageNamed:@"play_button"]; UIImageView *videoPlayButton = [[UIImageView alloc] initWithImage:img]; videoPlayButton.frame = CGRectMake((size.width / 2) - 18, (size.height / 2) - 18, 37, 37); - [self.cachedImageView addSubview:videoPlayButton]; + [self.cachedMediaView addSubview:videoPlayButton]; if (!_incoming) { self.attachmentUploadView = [[AttachmentUploadView alloc] initWithAttachment:self.attachment @@ -125,42 +185,78 @@ NS_ASSUME_NONNULL_BEGIN } } } else if ([self isAudio]) { - UIView *audioBubble = [[UIView alloc] initWithFrame:CGRectMake(0.0, 0.0, size.width, size.height)]; - audioBubble.backgroundColor = - [UIColor colorWithRed:10 / 255.0f green:130 / 255.0f blue:253 / 255.0f alpha:1.0f]; - audioBubble.layer.cornerRadius = 18; - audioBubble.layer.masksToBounds = YES; - - _audioPlayPauseButton = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, kAudioViewWidth, kAudioButtonHeight)]; - _audioPlayPauseButton.enabled = NO; - - NSString *audioLabelText = [[MIMETypeUtil fileExtensionForMIMEType:self.contentType] uppercaseString]; - if (!audioLabelText) { - audioLabelText = NSLocalizedString( - @"MESSAGES_VIEW_AUDIO_TYPE_GENERIC", @"A label for audio attachments of unknown type."); - } - - _audioLabel = [[UILabel alloc] init]; - _audioLabel.text = audioLabelText; - _audioLabel.font = [UIFont ows_mediumFontWithSize:14.f]; - _audioLabel.textColor = (_incoming ? [UIColor colorWithRGBHex:0x0b83fd] : [UIColor whiteColor]); - _audioLabel.textAlignment = NSTextAlignmentCenter; - _audioLabel.lineBreakMode = NSLineBreakByTruncatingTail; - [_audioLabel sizeToFit]; - _audioLabel.frame = CGRectMake(0, kAudioButtonHeight + kAudioViewVSpacing, kAudioViewWidth, kAudioLabelHeight); - - if (_incoming) { - audioBubble.backgroundColor = - [UIColor colorWithRed:229 / 255.0f green:228 / 255.0f blue:234 / 255.0f alpha:1.0f]; - } - - [audioBubble addSubview:_audioPlayPauseButton]; - [audioBubble addSubview:_audioLabel]; - - if (!_incoming) { - self.attachmentUploadView = [[AttachmentUploadView alloc] initWithAttachment:self.attachment - superview:audioBubble - attachmentStateCallback:nil]; + if (self.cachedMediaView == nil) { + CGSize viewSize = [self mediaViewDisplaySize]; + UIColor *textColor = [self audioTextColor]; + + _cachedMediaView = [[UIView alloc] initWithFrame:CGRectMake(0.f, 0.f, viewSize.width, viewSize.height)]; + + _cachedMediaView.backgroundColor + = self.incoming ? [UIColor jsq_messageBubbleLightGrayColor] : [UIColor ows_materialBlueColor]; + [JSQMessagesMediaViewBubbleImageMasker applyBubbleImageMaskToMediaView:_cachedMediaView + isOutgoing:!self.incoming]; + + const CGFloat kBubbleTailWidth = 6.f; + CGRect contentFrame = CGRectMake(self.incoming ? kBubbleTailWidth : 0.f, + self.vMargin, + viewSize.width - kBubbleTailWidth - (self.incoming ? 10 : 15), + viewSize.height - self.vMargin * 2); + + CGRect iconFrame = CGRectMake(round(contentFrame.origin.x + 10.f), + round(contentFrame.origin.y + (contentFrame.size.height - self.iconSize) * 0.5f), + self.iconSize, + self.iconSize); + _audioPlayPauseButton = [[UIButton alloc] initWithFrame:iconFrame]; + _audioPlayPauseButton.enabled = NO; + [_cachedMediaView addSubview:_audioPlayPauseButton]; + + const CGFloat kLabelHSpacing = 3; + const CGFloat kLabelVSpacing = 2; + NSString *topText = + [self.attachment.filename stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]]; + if (topText.length < 1) { + topText = [MIMETypeUtil fileExtensionForMIMEType:self.attachment.contentType].uppercaseString; + } + if (topText.length < 1) { + topText = NSLocalizedString(@"GENERIC_ATTACHMENT_LABEL", @"A label for generic attachments."); + } + UILabel *topLabel = [UILabel new]; + topLabel.text = topText; + topLabel.textColor = textColor; + topLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; + topLabel.font = [UIFont ows_regularFontWithSize:ScaleFromIPhone5To7Plus(13.f, 15.f)]; + [topLabel sizeToFit]; + [_cachedMediaView addSubview:topLabel]; + + UILabel *audioBottomLabel = [UILabel new]; + self.audioBottomLabel = audioBottomLabel; + [self updateAudioBottomLabel]; + audioBottomLabel.textColor = [textColor colorWithAlphaComponent:0.85f]; + audioBottomLabel.lineBreakMode = NSLineBreakByTruncatingMiddle; + audioBottomLabel.font = [UIFont ows_regularFontWithSize:ScaleFromIPhone5To7Plus(11.f, 13.f)]; + [audioBottomLabel sizeToFit]; + [_cachedMediaView addSubview:audioBottomLabel]; + + CGRect topLabelFrame = CGRectZero; + topLabelFrame.size = topLabel.bounds.size; + topLabelFrame.origin.x = round(iconFrame.origin.x + iconFrame.size.width + kLabelHSpacing); + topLabelFrame.origin.y = round(contentFrame.origin.y + + (contentFrame.size.height + - (topLabel.frame.size.height + audioBottomLabel.frame.size.height + kLabelVSpacing)) + * 0.5f); + topLabelFrame.size.width + = round((contentFrame.origin.x + contentFrame.size.width) - topLabelFrame.origin.x); + topLabel.frame = topLabelFrame; + + CGRect audioBottomLabelFrame = topLabelFrame; + audioBottomLabelFrame.origin.y += topLabelFrame.size.height + kLabelVSpacing; + audioBottomLabel.frame = audioBottomLabelFrame; + + if (!self.incoming) { + self.attachmentUploadView = [[AttachmentUploadView alloc] initWithAttachment:self.attachment + superview:_cachedMediaView + attachmentStateCallback:nil]; + } } if (self.isAudioPlaying) { @@ -168,21 +264,17 @@ NS_ASSUME_NONNULL_BEGIN } else { [self setAudioIconToPlay]; } - - return audioBubble; } else { // Unknown media type. OWSAssert(0); } - return self.cachedImageView; + return self.cachedMediaView; } - (CGSize)mediaViewDisplaySize { CGSize size = [super mediaViewDisplaySize]; if ([self isAudio]) { - size.width = kAudioViewWidth; - size.height = kAudioButtonHeight + kAudioViewVSpacing + kAudioLabelHeight + kAudioBottomMargin; - + size.height = ceil(self.bubbleHeight + self.vMargin * 2); } else if ([self isVideo]) { return [self ows_adjustBubbleSize:size forImage:self.image]; } diff --git a/Signal/src/ViewControllers/AttachmentApprovalViewController.swift b/Signal/src/ViewControllers/AttachmentApprovalViewController.swift index b76c3b8eb..2bde6ea43 100644 --- a/Signal/src/ViewControllers/AttachmentApprovalViewController.swift +++ b/Signal/src/ViewControllers/AttachmentApprovalViewController.swift @@ -410,7 +410,7 @@ class AttachmentApprovalViewController: UIViewController, OWSAudioAttachmentPlay isAudioPaused = isPaused } - public func setAudioProgressFrom(_ progress: Float) { + public func setAudioProgress(_ progress: CGFloat, duration: CGFloat) { // Ignore } diff --git a/Signal/src/ViewControllers/OWSAudioAttachmentPlayer.h b/Signal/src/ViewControllers/OWSAudioAttachmentPlayer.h index 514bd3fee..0c2098df0 100644 --- a/Signal/src/ViewControllers/OWSAudioAttachmentPlayer.h +++ b/Signal/src/ViewControllers/OWSAudioAttachmentPlayer.h @@ -17,6 +17,7 @@ NS_ASSUME_NONNULL_BEGIN - (BOOL)isPaused; - (void)setIsPaused:(BOOL)isPaused; +- (void)setAudioProgress:(CGFloat)progress duration:(CGFloat)duration; - (void)setAudioIconToPlay; - (void)setAudioIconToPause; diff --git a/Signal/src/ViewControllers/OWSAudioAttachmentPlayer.m b/Signal/src/ViewControllers/OWSAudioAttachmentPlayer.m index 0e2a17f8e..bca418e2b 100644 --- a/Signal/src/ViewControllers/OWSAudioAttachmentPlayer.m +++ b/Signal/src/ViewControllers/OWSAudioAttachmentPlayer.m @@ -17,6 +17,7 @@ NS_ASSUME_NONNULL_BEGIN @property (nonatomic, readonly) NSURL *mediaUrl; @property (nonatomic, nullable) AVAudioPlayer *audioPlayer; +@property (nonatomic, nullable) NSTimer *audioPlayerPoller; @end @@ -98,6 +99,8 @@ NS_ASSUME_NONNULL_BEGIN [ViewControllerUtils setAudioIgnoresHardwareMuteSwitch:YES]; + [self.audioPlayerPoller invalidate]; + self.delegate.isAudioPlaying = YES; self.delegate.isPaused = NO; [self.delegate setAudioIconToPause]; @@ -129,6 +132,8 @@ NS_ASSUME_NONNULL_BEGIN self.delegate.isAudioPlaying = NO; self.delegate.isPaused = YES; [self.audioPlayer pause]; + [self.audioPlayerPoller invalidate]; + [self.delegate setAudioProgress:[self.audioPlayer currentTime] duration:[self.audioPlayer duration]]; [self.delegate setAudioIconToPlay]; } @@ -137,6 +142,8 @@ NS_ASSUME_NONNULL_BEGIN OWSAssert([NSThread isMainThread]); [self.audioPlayer pause]; + [self.audioPlayerPoller invalidate]; + [self.delegate setAudioProgress:0 duration:0]; [self.delegate setAudioIconToPlay]; self.delegate.isAudioPlaying = NO; self.delegate.isPaused = NO; @@ -155,6 +162,16 @@ NS_ASSUME_NONNULL_BEGIN #pragma mark - Events +- (void)audioPlayerUpdated:(NSTimer *)timer +{ + OWSAssert([NSThread isMainThread]); + + OWSAssert(self.audioPlayer); + OWSAssert(self.audioPlayerPoller); + + [self.delegate setAudioProgress:[self.audioPlayer currentTime] duration:[self.audioPlayer duration]]; +} + - (void)audioPlayerDidFinishPlaying:(AVAudioPlayer *)player successfully:(BOOL)flag { OWSAssert([NSThread isMainThread]); diff --git a/Signal/src/ViewControllers/ViewControllerUtils.m b/Signal/src/ViewControllers/ViewControllerUtils.m index 180e25fcc..aaebb97f3 100644 --- a/Signal/src/ViewControllers/ViewControllerUtils.m +++ b/Signal/src/ViewControllers/ViewControllerUtils.m @@ -90,13 +90,16 @@ NS_ASSUME_NONNULL_BEGIN NSNumberFormatter *numberFormatter = [NSNumberFormatter new]; numberFormatter.numberStyle = NSNumberFormatterDecimalStyle; - return (fileSize > kOneMegabyte - ? [[numberFormatter stringFromNumber:@(round(fileSize / (CGFloat)kOneMegabyte))] - stringByAppendingString:@" mb"] - : (fileSize > kOneKilobyte - ? [[numberFormatter stringFromNumber:@(round(fileSize / (CGFloat)kOneKilobyte))] - stringByAppendingString:@" kb"] - : [[numberFormatter stringFromNumber:@(fileSize)] stringByAppendingString:@" bytes"])); + + if (fileSize > kOneMegabyte * 10) { + return [[numberFormatter stringFromNumber:@((int)round(fileSize / (CGFloat)kOneMegabyte))] + stringByAppendingString:@" MB"]; + } else if (fileSize > kOneKilobyte * 10) { + return [[numberFormatter stringFromNumber:@((int)round(fileSize / (CGFloat)kOneKilobyte))] + stringByAppendingString:@" KB"]; + } else { + return [NSString stringWithFormat:@"%lu Bytes", fileSize]; + } } #pragma mark - Alerts