From 9cdf907e20e96f5f36d7a7e985dd7ee1c2b700f5 Mon Sep 17 00:00:00 2001 From: Matthew Chen Date: Fri, 2 Jun 2017 17:17:59 -0400 Subject: [PATCH] Rework and unify the system messages. // FREEBIE --- .../empty-group-avatar.imageset/Contents.json | 11 +- .../empty-group-avatar.png | Bin 0 -> 12034 bytes .../Contents.json | 12 + .../group-avi.pdf | 0 .../Contents.json | 23 ++ .../system_message_call@1x.png | Bin 0 -> 1810 bytes .../system_message_call@2x.png | Bin 0 -> 2599 bytes .../system_message_call@3x.png | Bin 0 -> 3479 bytes .../Contents.json | 23 ++ .../system_message_group@1x.png | Bin 0 -> 1594 bytes .../system_message_group@2x.png | Bin 0 -> 2117 bytes .../system_message_group@3x.png | Bin 0 -> 2666 bytes .../Contents.json | 23 ++ .../system_message_info@1x.png | Bin 0 -> 1674 bytes .../system_message_info@2x.png | Bin 0 -> 2428 bytes .../system_message_info@3x.png | Bin 0 -> 3343 bytes .../system_message_security@1x.png | Bin 1853 -> 1669 bytes .../system_message_security@2x.png | Bin 2728 -> 2426 bytes .../system_message_security@3x.png | Bin 3677 -> 3158 bytes .../Contents.json | 23 ++ .../system_message_timer@1x.png | Bin 0 -> 1772 bytes .../system_message_timer@2x.png | Bin 0 -> 2443 bytes .../system_message_timer@3x.png | Bin 0 -> 3121 bytes .../Contents.json | 23 ++ .../system_message_warning@1x.png | Bin 0 -> 1678 bytes .../system_message_warning@2x.png | Bin 0 -> 2361 bytes .../system_message_warning@3x.png | Bin 0 -> 3015 bytes .../Models/OWSMessagesBubblesSizeCalculator.m | 210 +++++++--------- .../ConversationView/MessagesViewController.m | 173 ++++++++------ .../ViewControllers/SignalsViewController.m | 4 + Signal/src/environment/NotificationsManager.m | 16 ++ Signal/src/views/OWSSystemMessageCell.m | 226 ++++++++++-------- .../src/views/TSUnreadIndicatorInteraction.m | 7 + 33 files changed, 471 insertions(+), 303 deletions(-) create mode 100644 Signal/Images.xcassets/empty-group-avatar.imageset/empty-group-avatar.png create mode 100644 Signal/Images.xcassets/empty-group-avatar_old.imageset/Contents.json rename Signal/Images.xcassets/{empty-group-avatar.imageset => empty-group-avatar_old.imageset}/group-avi.pdf (100%) create mode 100644 Signal/Images.xcassets/system_message_call.imageset/Contents.json create mode 100644 Signal/Images.xcassets/system_message_call.imageset/system_message_call@1x.png create mode 100644 Signal/Images.xcassets/system_message_call.imageset/system_message_call@2x.png create mode 100644 Signal/Images.xcassets/system_message_call.imageset/system_message_call@3x.png create mode 100644 Signal/Images.xcassets/system_message_group.imageset/Contents.json create mode 100644 Signal/Images.xcassets/system_message_group.imageset/system_message_group@1x.png create mode 100644 Signal/Images.xcassets/system_message_group.imageset/system_message_group@2x.png create mode 100644 Signal/Images.xcassets/system_message_group.imageset/system_message_group@3x.png create mode 100644 Signal/Images.xcassets/system_message_info.imageset/Contents.json create mode 100644 Signal/Images.xcassets/system_message_info.imageset/system_message_info@1x.png create mode 100644 Signal/Images.xcassets/system_message_info.imageset/system_message_info@2x.png create mode 100644 Signal/Images.xcassets/system_message_info.imageset/system_message_info@3x.png create mode 100644 Signal/Images.xcassets/system_message_timer.imageset/Contents.json create mode 100644 Signal/Images.xcassets/system_message_timer.imageset/system_message_timer@1x.png create mode 100644 Signal/Images.xcassets/system_message_timer.imageset/system_message_timer@2x.png create mode 100644 Signal/Images.xcassets/system_message_timer.imageset/system_message_timer@3x.png create mode 100644 Signal/Images.xcassets/system_message_warning.imageset/Contents.json create mode 100644 Signal/Images.xcassets/system_message_warning.imageset/system_message_warning@1x.png create mode 100644 Signal/Images.xcassets/system_message_warning.imageset/system_message_warning@2x.png create mode 100644 Signal/Images.xcassets/system_message_warning.imageset/system_message_warning@3x.png diff --git a/Signal/Images.xcassets/empty-group-avatar.imageset/Contents.json b/Signal/Images.xcassets/empty-group-avatar.imageset/Contents.json index c8b0525d9..00c7b2c36 100644 --- a/Signal/Images.xcassets/empty-group-avatar.imageset/Contents.json +++ b/Signal/Images.xcassets/empty-group-avatar.imageset/Contents.json @@ -2,7 +2,16 @@ "images" : [ { "idiom" : "universal", - "filename" : "group-avi.pdf" + "filename" : "empty-group-avatar.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "scale" : "2x" + }, + { + "idiom" : "universal", + "scale" : "3x" } ], "info" : { diff --git a/Signal/Images.xcassets/empty-group-avatar.imageset/empty-group-avatar.png b/Signal/Images.xcassets/empty-group-avatar.imageset/empty-group-avatar.png new file mode 100644 index 0000000000000000000000000000000000000000..c18015bbff8a97b9314842883c9d0914db671cbd GIT binary patch literal 12034 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 GzyE)o)_oQL literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/empty-group-avatar_old.imageset/Contents.json b/Signal/Images.xcassets/empty-group-avatar_old.imageset/Contents.json new file mode 100644 index 000000000..c8b0525d9 --- /dev/null +++ b/Signal/Images.xcassets/empty-group-avatar_old.imageset/Contents.json @@ -0,0 +1,12 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "group-avi.pdf" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Signal/Images.xcassets/empty-group-avatar.imageset/group-avi.pdf b/Signal/Images.xcassets/empty-group-avatar_old.imageset/group-avi.pdf similarity index 100% rename from Signal/Images.xcassets/empty-group-avatar.imageset/group-avi.pdf rename to Signal/Images.xcassets/empty-group-avatar_old.imageset/group-avi.pdf diff --git a/Signal/Images.xcassets/system_message_call.imageset/Contents.json b/Signal/Images.xcassets/system_message_call.imageset/Contents.json new file mode 100644 index 000000000..4d7738bb3 --- /dev/null +++ b/Signal/Images.xcassets/system_message_call.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "system_message_call@1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "system_message_call@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "system_message_call@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Signal/Images.xcassets/system_message_call.imageset/system_message_call@1x.png b/Signal/Images.xcassets/system_message_call.imageset/system_message_call@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..41257d76a3720d09042a36464ce9056bce5835b0 GIT binary patch literal 1810 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1|*NXY)uAIjKx9jP7LeL$-D$|I14-?iy0WW zg+Z8+Vb&Z81_llpi<;HsXMd|v6mX?-X(Gs7c7{+3kj2o|M`E)8SrADBDCn&MGAmMZB3v?o0Sfko5zrf0CD1iG=jY@X z1s5bHr-B>?)`BF2t{QAjBra=^B#<cpt8_^$NwqUFFf`XSFw-?K3NbXZGBC3;Gq%x3Q-kCJkc@LtYGO%#QAmD% zjvd$+xgf5Bv7Q-3C$c;NR|bQ0`sgL7f>fG|J!l7tva8?z`)e$>EamT z!Mk*tceaS5h@1L81*!N-g~*ixLY!^~?H@Sx{9_2`N)vWu6}-En@Szi{>ZEvqm>r_w zdRJlvT3JMeL=8D!IVo#s%;4x+Up#ANz}=U#GLQ57m0w+3ogaEVd)eA+G1`SM+ZAuH z-F|4gr*XLf`~C&0xeBjXY+B?$EN6MU?e+5dmAAasZoTFBCOjd0Z|%JA!WFFC7Z__d zuva;rJ!H8fdFjk^j|ANQ&G;1f!jmO)d#wHbD;AHXz1Zj0A6AWE4}CH{mhEwme_2U` zoBJo>Igi6iCMlRVR-TzYx%-=pOl$lH`%m3xlK0(7D_}9(vEyyP6+52l?qe>sx@Dhd zoZmAu?DHJ9-gaZ}e}+z9t@kwCIq@lP=PkjkXU6M)W;Z{O+1GqlAe(!te?r5Yb}ggx z)due$aLLU}sjg<3uQ=`PqO=4fZPWT0$7`O+8XaWN;ExKFH>hB{Qo3XQ)K#`l`xvc1 zmT3DI1^Qj=-E}cHcFws)^)dWEzuorS!FKJqT;NZ&RQtR7`=oB}wUE|)vO8T}|Mk4T zogMi%{11jpu)g0STfnX7sr z@5fpN_RA;p=?U?#4coU|Y|>{`KVxUFQT+_Eeq;*P1KSYO$y{!1Y&b zvq1K|wo3rK@Z<9)HMaaXeA$(e|?2U%A!iB*m@N@7#N5(Y$+eH;9@Y6tCbue?a(clKNNi Yuw@Gb@BZ`H0jj7xUHx3vIVCg!08)F0od5s; literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/system_message_call.imageset/system_message_call@2x.png b/Signal/Images.xcassets/system_message_call.imageset/system_message_call@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..46e4d44a3e33ec5acc1eb7efac43ad39d3090f00 GIT binary patch literal 2599 zcmZ`*4LFl~8($&K2>C4D+8J?`*asFfBNO@96k^T^%{*AKt$k#O@)5aAy^b;|5pVSt zrgh@z0~4)I_EH=l`RI_o=wpf#mGnMCwd1Pix}J~!egA&{-~GFv=f18ddmGtPOJlVL z1On0W+Uo8P-Z6@E`7-dj#^taWye;AQd%8hHZKk8(0?OJN!ht|wdWv%ir0A3}1fq(d z2U55ck}rczxC0y-o6h3WnGCpMUup!C$8|;^6hdE*`8v7u zsBcOP&Vnt_AX1S*qHR#f@6iB0{RcEf=7+RM+E-UB9y@lI;AS=BA^!plw*tWA>R{F4k{58t;cPn^MP23I~{E3 zybBZ_`Q5}~B9R%(WCyUQG(b_<97QR#7(FKw@*^3ggc325hU4%eb^|o7(%S;x+1$79 zMvX=)h4IMmqVeFDfFm&@=}`&pR4zckpwOGFQCMpfCJ>Fqp|CgyEFQTCqf~(+Lu3O~ zE|VR|WX2NaT*N7sa9f)NrgDCPibpD@NNK9(M|Lg>&MZL#)ci941dURcRnriN+G#KM z&4Dp$uL>VjhX$D5c7kUHUBGhdVtk4Yk4tjyZH~!DJVLsfx2R|b>I7C>MqD&@)4cj* zM~euCr5;tMWRLe9HTxdoqaO4Bn9bN6C7 zBaf79o&JHL>KXAQg!1?$M_QeET(}emz1>l_Y#1e^q%bLER zoV+0ez{)rAeP=&Azc33;^GOjr=*>c%4BEK&S#VAdegul$p_Y0$H&`YG=Kqbg_JV_C0G+?Z)F zQLV6(dpHz$^tVe2WlKM#k6TdG6RtMGSDzqRt~s1?#@{8ZOt&wKSV1{0YZVkjtFv4V zO|`}Zr+(i124?=z@GRA!V^vP@vBptk25(o_2OW#((b2a)ucjx-!UBi?iCFJ)tw#^| zI;FfSV5iV0xgywv-W5T_$#6!KO)@#Swx|PTA2Oran!diX(ff4bQoJav zL1WBX_E=72soO2DwyPLgN?De#+qayC_%x``t8)%u*<#hKWGnfGrr}M`lkZ5)1@|e} zBOICK9rDR4Lv>ir-WhcPdez9`!VLG>k~btlLbqwmsWf5^+4p9zK&+1+ow(LmAfCAv zewRY}N!W%n&PSc=*1oU->&z?H?YH3UHZZdXo|OqL&wRePDYYPJ(};JW<;eMc%|{IJ zCfMcyxwrJ9{_>Wo=D!Bpn+N_|GQIgZ^r8Nhnx%>9ZQwMve^$9CaZTM@tabD3xGKeH zEK%>F>V)b`ZOQ3;i3jXq`s;%Ut9*|%J{b(SS5n+LOzDL-1bBq-{v_>t6cGMzq;-N+yO(9XbTF0zoTNYrl#p zbJndY*J5RMTh)Z^&>xqy$%p93m!{|6D{DPsTt literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/system_message_call.imageset/system_message_call@3x.png b/Signal/Images.xcassets/system_message_call.imageset/system_message_call@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..befa6647ac760079fc7a24968952eea83ce3cd67 GIT binary patch literal 3479 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 literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/system_message_group.imageset/Contents.json b/Signal/Images.xcassets/system_message_group.imageset/Contents.json new file mode 100644 index 000000000..b08517114 --- /dev/null +++ b/Signal/Images.xcassets/system_message_group.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "system_message_group@1x.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "system_message_group@2x.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "system_message_group@3x.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/Signal/Images.xcassets/system_message_group.imageset/system_message_group@1x.png b/Signal/Images.xcassets/system_message_group.imageset/system_message_group@1x.png new file mode 100644 index 0000000000000000000000000000000000000000..282b5bbef9da801925b43e55fb493c6adb550825 GIT binary patch literal 1594 zcmeAS@N?(olHy`uVBq!ia0vp^k|4~%1|*NXY)uAIjKx9jP7LeL$-D$|I14-?iy0WW zg+Z8+Vb&Z81_llpi<;HsXMd|v6mX?-X(Gs7c7{+3kj2o|M`E)8SrADBDCn&MGAmMZB3v?o0Sfko5zrf0CD1iG=jY@X z1s5bHr-B>?)`BF2t{QAjBra=^B#<cpt8_^$NwqUFFf`XSFw-?K3NbXdGBC3;1G*he4U!8$GR{S*i6!|(A^G_^ zc3@xRg18FCdS(!v$nsFFHu|7kgp{iwSr#k`%(He}K%KDsZ^y+o*?j@9IN9jw;uzw= z`*yOm_Z&x&Hgm5>ygG|MZcCahAdqt;ULj0Oj5|r0<%(UZg6Bl1Pv$KmnUgrgx~AUH zp5eA3z_H+{cZi5!k!t0e&;T~y6=O*bF=iabLO*8Uk#mqAl7$*;o^@LA1yOl z@Ak~H_`{ISl=eXJjic{g#oy*hcB|_8{;umOn_&8J-gU*m+_x$f({gqkdf${@An~;8 z=?&qq>_^UiAFUTGX-k-L-F=O(r_cSuJq`afrt2R+vr~UswbsTj6ND#u7n*)Es@OeE zWnK0g=`}B0Hnnd*IYs`RXieMp3p`mYk2YpV2VaYLE%*J_;zh^0zTVGBpV`9rgYn)L z_BsFU)*RBm(J=jk=$}5;7tQYz&gWS$R8L8JyNd0hGS6$3UoHC?7AFLk^1U|T4xVsI z-hkIy@nYLX&X3%j-^4z;{)ko0f5ROi{Oa*l>D#+i)=R55*ZTfp{&Vs~box1|?8Eyi zbX%@J?Z{J@dOwlFDR$O%^Yq@WE8keYkq+PY+9u-7{Bt{hpX)ymewlG=iQ^~R8;{lJ zG`HtD8_G1zU1?~v_k+Zo_rU>XJ6pXi+Duohwri}Ocfg)iuIzA@xxi{rf$r(*=d#Wz Gp$Py8e=9ox literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/system_message_group.imageset/system_message_group@2x.png b/Signal/Images.xcassets/system_message_group.imageset/system_message_group@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..03abe643a0a095ee3a116c27537dd7707b06a133 GIT binary patch literal 2117 zcmeAS@N?(olHy`uVBq!ia0vp^Mj*_=1|;R|J2nC-#^NA%Cx&(BWL^R}oCO|{#S9GG z!XV7ZFl&wk0|SdvW=KRygs+cPa(=E}VoH8es$NBI0Z=sqgH44MkeQoWlBiITo0C^; zRbi_HR$&EXgM{^!6u?SKvTcwsYk*NEcCio^nlW#B-B_{|37a;u=! z;{2RaP!NRXWtP|(*?>KSE{q5fh%V>++=8Oi;$omSJ5#6@WHEI05eRGS%wcvQ3!-cA zFUkb^G!f)3J42`i$YSW~Be7Y4EQq856!caBnH8xy5iXg)0EPI%z(yad1iD7&{G9xv z;DW^DRFK2KT9Aa$RfDaG#AOYV1d_&-WUJ!Rq^#8B5~SDy#u+&6J0+&;BMIB+V^wVf zObJ%L`6-!cl`e@Tsdh#NhUU5kX1WGOA%^Bw24+@9z*s|5gX98`jB`}GamIaFf^Q;{gP$w+^+i`8&($vJjz`V!P#W5s< z_3bp@j<8UPF%=$6azrYGm-6OY3ot3FOf&KS12FTYuWa+Olq z)971z$5Xvq_qZL8Ub7FMd8*In;(tY+MQMl5U5xwMZ}&^}LwB~tBv!af;9TS&LHMMwiV*Z!2fy?(7 zepq>J;x^$>o8>=Wi#_HpnmPT_e%8wQ5%Kc1&1Wt)&B))7%YAO{mUlP8cCaWWX7neW z)^9sK?_>c>lYivu{(Y6aMTIRrVR-{V1+!y@FX>s`Z?svlgGyH+vQ(-~4+EySL7QQ)OKe^BtC3ckovBnzrw3TATTL z*87Vw>uR)2d>72uH$A`q{p7MoN&D`n08@&z{^p%&*Y7JI~zgi`kqlzk6c%ttnvkmi}OIktD5tqt3E;k!*&H?YXHuA06y zx>k~HVYJb7%d@fO-z#hC8WcZ7^x2-@zf6A>e@&%sllp<>Gvl{jKCpfFWQ&EDuIYYF z>-=`{T+{9cr$1U*+<#vn*7i_+2Se<|s7*88uvxsUFlYx_KXFao@=p=x*ve0Ho${H% z7xvxp!Z(!_@(0&vh}$yN^~JER)(t|{Xy*l22WQ% Jmvv4FO#tn7KJx$o literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/system_message_group.imageset/system_message_group@3x.png b/Signal/Images.xcassets/system_message_group.imageset/system_message_group@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..b57da5eb18e7644ad10f6ae1275923cb808fa1fb GIT binary patch literal 2666 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 literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/system_message_info.imageset/system_message_info@2x.png b/Signal/Images.xcassets/system_message_info.imageset/system_message_info@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..5b012a899e13f875286af0dd6eb00f3fbfe886d1 GIT binary patch literal 2428 zcmZ`*3pkr+8;;-9&@>xbry+|vY$Hbv(nv>wqUu~RHjVgbA}2}wqL_BnVL}hCI+q%H zK$#w}c9=uizm+n_Dy6mlXjL7i)T#fM&^EtIb6sD)@4cVre(&dgzW2$MWVgc(P-Sgp z2m}IkJV@~X?^wz8@ec4???6%&c#{)&IM_leIzF2O7fQT?z5)nDMNM+aL2~jmA&`#{ z3@@sX>T-xc=dzKsAZ{Rl6tQ_=HUvTx5x_?_Af&-XY!*jA5LqLn83gcI0;3RcX^Jq^ z8bNh&gOj;@0KN}tjzl9!%5XTG$PWr8cu?#&>EOy5aZD)W5m2azhzMi^4$0+*pfFZe zRwy(Ug~ghI8D@e=j*uoY;|L5kHhH@b1rX5r44#m|<-jHT(gL~RLTdy2Lu9;M%uSY zk;S&=Q{T&wEZ%C!f?El$dOxgG*m57o|k<3(WjI0y|XO^T4GT+WWNqG%v@*MoNn0KVucpX!C zk-cB+?X8~Rfcre{NBgb;G<>wIv#G`QnmE%*gWIBQ;UsOCVNI}cv|^!8lzthp=)&wQB4Lj>Z`lgt$!Fi_FS{=+1PEG;@R=X zzLri)SH6##a4t}5-h4Cr?dG6;@MTjdk9!kk4(x zr1d7&J7L7v5{`5>D*miKy7$HX>N%1nHDKBFt_L|Bdw8Umg(`3TB}xuLqAGAaMd-? zh<~#69!&1m@L8RVXY=N*drj|fDm5M%@hTirp9k)*)1ZB}WVMi^Huha>U3!?t!X@-8 z4K&lE=$phRpIC?err%Sb#jN|jjh>BKBh{~;DXe3x&AFL3Kg$6pk!8;DaC z6IQ0&sq*`-7#dxteB18xSmB$W3UgUgYEQo8dV0dT{%y77U$V+;TLV;e~#I_rY}YH^%a*+WFzqFN#|9wOY$0eqJOecu{6Lo@^dNwq=$Ok80=S_rRG%?!UF6XoX-Cd%3$1WVGfl# zvXz+Ax|0n1>Pz|S3l0_6q3XJ)#uv0l48OI0@x|E{T;*3iF&zx~MTh?6D~{|>CEzau zU6?7N5htg=a|g(;krT2lhQ6?kZ9KE|LoBr87 z8}dh3Le7#?wWCjIly2v=Z?w|wY}K{fRb3Y^72hw*QCvT5+Rf9mC+dE69>{ETo&iJ= zC8sS-`-_8b!A7l_7{50ukIavDm0#aIkD|>@%8#&c8uEQ$tLDZRem`N?@Ye!;Rmay& zzQIqK82pekMO+9(+-+O36W7Nn>4hs^?AIRh*EH{Qh-<1nmti=yN2R*%5;7oM|Fcv3|L$tYW&RIR&k-_$;MCAHp0JbcW7^Q*-01bYi2A9(uW$oR#!6c6c1F z7N%Qp5~F4DfMm(g#EpzHb)qUGZT&$=zi_e1v60#;*6t~;wzo_Q7Y6#at>{Ev#o_Jq zK1JCVkeBsgV~K oD0h53v(VB1MA=Mi%l;XdeX8aCQ@SGtlD|Zbc84hywnu;XA6Ajwk^lez literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/system_message_info.imageset/system_message_info@3x.png b/Signal/Images.xcassets/system_message_info.imageset/system_message_info@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..fdc2760cedd6d24f7205bc71420598d126c3b159 GIT binary patch literal 3343 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 literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/system_message_security.imageset/system_message_security@1x.png b/Signal/Images.xcassets/system_message_security.imageset/system_message_security@1x.png index efdaa2b0c329d74343923db0d8c44e98d65bcc4a..ce619b65388f1cad761d25c4a421b9b0453e38f6 100644 GIT binary patch delta 609 zcmV-n0-pW74uuUNiBL{Q4GJ0x0000DNk~Le0000P0000P2nGNE0L1BqW3eIH0s=BM zll=l^0x~s|WCMW*HaajiIyNzr>;r*+HPUa|0005}NklIeoM$p>7#Do+=w38G8D-}zzw6@YF35Z%43zH(?=lN~!#C5oL z-&-{Y&YL?k=gi%YyRRXuhF;01#9!h`HEV74J4u$rKjL+WBw?&5YXzF<+{!!xZ7nAs@4jX(D-y~J>26}w>OAp0& z2{<|JVhn>SeinyfP1W$>|5ofjDJEL4iOMd3VUKLcC1$&1Z9Rncw74RjxL5dXCiF5Q#D1 z!_S-~I34@qR#K5=ttCBt_?c6RWp#gxoe|ZfYTU(iq=z0K{yXrGi{`3-$mtpCCkQCxfZ{Owf?&4qeG9c5j)B>yiQ;2W6}iFM-!vfXaUMOL0j00000NkvXXu0mjfCetCP delta 794 zcmV+#1LgdM4ZRK_iBL{Q4GJ0x0000DNk~Le0000U0000U2nGNE06Q?QqOl>`0s=EI zll=l^0y8j^WCMW*GCD9eIxshr>;r*+&zw=50008CNklj+0d!4oZ^{+W+pT`Uj^@pXj?GLTfte^U`>Aq_e=_&Xa{th%YXKmnr*oNZ; z_!7o}4~b-Eazife!cuZ^46bQJ}FoYiiWmW3L`vV+qPbumR)Qd?daM zcfvYYQ=>NaHHh`nvn_T}eFS6UEb)1`33dy$_ShSJ^whf+AE+pP3Xj9puwU4#hhBQV zhqZV`MbYV6MXNB*axrj62d!RzdV2E}sBZqfP+3?g^1%kuM*=tIB}F!RMek;zI{1E& zM{&_z3BD%BX`G~sFnT>GG6dDZ(PVKd%EaH3+_xmoh0!Z|H#OD4pF?M-+dmzg#<{`K zD|%-K`wWVa)>8YM4ol-)!}5@f-p#}68NUspRXK+w=P>V7(P{9?mTc&MO<0>tb+C_< zSPSPjqx?@C>}#^!U_JB_uUkv&w>sEo%}?Aq*zR)wq;9YL0qdZLUV4_E;{}xt|Ed>o zGh7ejr6(-m9Y;6dFf^`%9&XzcSUTfe!*!DG-{D-b$DAH|=~+VcQd?{U#on;y7WeH6 zyb9OAIz*2~ogmHo3Up6@{9ug19L|vROys4UfSf*h=rsmQ$erV$DnZ)_Smb3UOnL~YA@w1+}cB@T6^r(qi1*~ zH=zd4;5h6AHEQj#H+MBicg6}Ncc4b@>j78?YiiWqhW5@0BXmzyK@ELNorCF_7@M=E zMy)*qfp54;7~j!%iMIqAJJ8xBR6B6&!!homUmNLAbJqSTMsdFe9Vm_c5d1exFiG}> YKM0Jb^#>;R4gdfE07*qoM6N<$f?~aN{r~^~ diff --git a/Signal/Images.xcassets/system_message_security.imageset/system_message_security@2x.png b/Signal/Images.xcassets/system_message_security.imageset/system_message_security@2x.png index 7b995d812e9d5086306f158ef3318ec36a4f4a26..62e68343599d24365e8b1197ce553a27ddee6499 100644 GIT binary patch delta 1370 zcmV-g1*Q6^75Wk(iBL{Q4GJ0x0000DNk~Le0000o0000o2nGNE03JVxv9TfA0s%FX z`~qeHHIrilf(JG_Fg7|iGL!5Bfq!x%n-Ks21o25kK~!i3?V8DpT}2eeGZ+U14WxlEZnD(n@~r0E|YAUB5( zzQkBCVc$O|d?VzN{9fZP3LAx+20CLoTVfDvy)Z9wzF6)R-Vpu}a!Kve_*UUcAr;1$ z!zSlTOk%?USLbqtB0eU3D1Vd^*sZzygbRd8f(^F#lpY9NaKe4Y!nSxp_)f?bz?OJk z*dVkOe2G!oqHvP~xipq3dAu(CDdY<1jaOKN>TkzqW6ebUdVbu_z879(QaV)L~s+#gx2{W-^Fxj~J6ZsPB5?bI^xTHIlvd=|p~dXBy2$#qDl6h!Dec$Bxqn!OenvdEVT@8CzsMpE z74Pw>p+~)vu1LDoY9poum=s$CUwwGon2qpihXZHFwtwWimq>6g6iidGQd$uVzclN0(#P4F=}@H* zzgnQPN=*dL>wnDQ3)4?io#?a)b^N}yR{cu_eg&x&lHMs?HE=knwrL@7!X1*mXT@Zx zy-gE5)wqJ+Su*T#{4V1s7jnu9OIMOlHSw)Y-eLNDsm@6*H zWThhQ7k`4_xbz1)i#`{Kn8XeqIN|P8cncj7f`mVC?&*+$Scfe>TyXXxk0|O%A&P-` za|cYs@FL)Vt5?~s=ursm31QnAFyc!Lj|s=T2;{ypB*8akRRi`Z+4{GF7+fl!Y!IUp z(=CePXNE+$G1q*(vBB0?fmja<3nEug}y8jAePYK5a_aO$c7F77~ z?G`*S^mhcm1)%Q{QagN!u_%O_DhD*(YJ8R1^PDNa9Z(Fm_%yvy%cXz0SrqRJ=~GYp z*kHS;gFg7|jGn4ECfq&5vm%ji21|La8K~!i3-I`mdRaF#*)h?zfl~Ed0 z9E!?r6j6bM(uIhKdg=BOJxD^-gF;Wz?HEK@FX4maOF~9aJ!JXXji9I~D5J}RC`Bi* zFe@vMU9A7}?6vkdgE{9~bM3YEKF0ySYhK3q$3MxwSSj(hpu~v zFJU+tmn+Ri;d|k~9%wVh+)-mIRmqFO0ih_=Uzyt`;5#dAp;X@~yea%E_yS{ne2F0z zju~(4&$Yr%AyyRQKlhOGfdei$XPjLqMNbP8LaK<}njaU&dZ5i%Du#UyH#tUbtE8Z6 ze^SiH!W!We!5d@D;gc$yeSc0aat_rND%)McTS97o9@6|9!Y#saLY3izFEPZ%iYF(z z(SVlDY?+wX310{?F^umMo)fMVni{ciz?I5{7Br!)HDm8QBTNXX^Yh#7IHm|+RITH$QV}*I;S!-0Ve}ycvj1Afx_d+YoSfit$(claA+Dq5e z3j5Q_Vnz9=r3(H{UhJ>JSYiKgDCX*3V=K%#xT&GZ z7K~=J2d%1Ldw&Rr)ZaQm(!^kFg%cr_Q)sf=?V$RN3%0igq=SCQ@1kHd*@D@>jS41k zzfc$_t<#E5!)q4>pDr!-6o}?V4=wiFURT(euAkct6&yVz)Fk(s&>VVJ9HC3?VI00a z;?@7>oPM)WD^zf3EQj1{@|ve{RTaEzn)jSJ7r1_IH-EI6p|Kp^^PRKTJZ-wFVE-{| zxuUCLrX}dOgBCPd^P25ku(KgzDx@|nb-Icik}6Znpc zzES-;aepqX?DA{jRl?Q6l5#Y^fd;f#d)IcFwl7g2PtxMH=IC}&L$Z4mw?{ZEz{e|O zwa~;aR?wtS=t3h}2R6RE`$#B=x$-kit|5>=mgS+%d-yUT*Pc*-99HZLk(k&pxzS)b(Ab)tB_{q~hJQ`4Hk18X7jL=V&*WO?xX^~iR&BG` ztjG!V&&bGdor||zH)ZgUliW5QZLQmRV&r3&O|&&53;S!6P&}{-o-G>7`I4WUMJ(4} z1%JHMP&@XNXlydX-M>=ToNTsAja z(0|maahy9O*u=a~dF^y%aFfI4L<3reV(XQ~Ca2BEvQ}RFt^zpW_W95-G@GYPTLmwI zRanuY3b_2rlJj{14MVjB%C=qbMeozt?JX#|LmY5<{?{}{?vWT@-G++hb16^ZCaXXU zv2gfe$+bursqsVBHo=Rd|BA3osB8GXDu0By$l-r9tIONE9|wnxLP#jzK-77f;)8F9 z1MZx|iQI={Ym~;H#wcJ?cwCq-cw>w?e0;HR-6zawyGH8161;f&Zwr?Sh0$g#;8MTN%jC1zIJBi5Gv4);e+o{VMiPk zHV6j=TO@79#)Xj`CX~A~(~j{X~n^yt~(ZS=R&osqS0<1E5o5 UDb1xhjsO4v07*qoM6N<$g2hNYS^xk5 diff --git a/Signal/Images.xcassets/system_message_security.imageset/system_message_security@3x.png b/Signal/Images.xcassets/system_message_security.imageset/system_message_security@3x.png index 315db79734e6a39ebea1b25e7b67a3e5fdda05a4..a82724734781f39b02720f7fd75ad3135991d6f4 100644 GIT binary patch delta 2109 zcmV-D2*UT>9M%{iiBL{Q4GJ0x0000DNk~Le0000>0000>2nGNE060#1>aii(0s=QR zll=l^0yj02WCMW*HaajiIy5(v>;r*+Y9J`H000NgNkl2@+JSwtZ&x(fB)~>Gi%nYU8_x4bOk1VMfa?x zBYGAKD}{bxkMOTBVVMd{)A@j~NuW3mv6hZ}w@iQJC_~0EgHba@*C43~r6yhKC+bM92=?^db z#2K}Awv<02>=j~?{#pHA5v~+}rj8tGULm|J928=b+^2qz3JV3x z@N=DhF?_@&K046Tb9Ss0tr7->*vDs!`raeV6k?2i^k-a5(a~?Y#l%J5S^>S4+ag7LO88oc5z8z8S>a+KrNIY(FZ?k&(2H*L zchn|}eW~!4@VgKr&MhYAs(&X9{+PwB(~N%dARqEdYJ9707F@8r<0kbT5T*%L8u11M z;^%2}*U5|glGtTp`Acx*q2n*=^O|tAFiGg95g#4sL03q#^ON7DLTTG321jZgztr_7 zgmX(r>I?z8(1%V-zw>>6k|Mk#^N$~ke2p+GMUV!9m=ZumANM=rTPs7Ko99x}8rx3#n*TV5T$ctD5gUcaNfcG>1} zB3LI_D{YcnFQ6lpS^9s-BabN-3%U6oQR=rH+bpXEYpL<8{7le)DT`(4C(o7^^BC?m z7-EWS3=6t=bz6@+1MqV_rCIu|JR4%h6pOtj-zNKxlI=qp|95}`f9P6ZNUqz`Z{^uQ z6jQA48%7K_tY_Zn7VV-~p}Pk^*Hapgy>C{Y4SiyY#h1NrRxrO$JMFwXtBPWUeyn;P zF~wq?)oRXa5S^f5 z{n$y0#iG!kGYDp_Rm$Yi>dq>|>yJe@pI2EUztEz%-Y@2V&f>47Kk6ffPbil4M)A6} z)vT&m==Sd{@*~fd7E>%L?(Z-V%$g)y2FtlvRk4__{9=(`k~@oM*(V~P_0cPLVXLZG z$4j9~Gu1Rmwue@~41OK{OcM{uc=OC0RPK#`#9@ZIsXTlqDS#TM)HrjgCNr$(2yT%kKC2-^4hPGis{%GP%$CGvL&spRZ z^%z=v(HZXg=~p^qkNTXtr&eRVa^{FX<1T!PzJMY5iq2j0H1lNjt^@}*G3&@&|XTG3ybu{PlY*B9}02?eV(mQA=UCzJbs zZ6!F-ljY+a-5pt5wbJ>LA%u_KGH;kU8c%W73rza#Y!o$gpvNy3x+}N2is;`72xAGb zpmH^h0T+(w@C$`rba%y8E2=Mu_Ev%IkZu@piErsbZ`W*+BEK$J!UpB%^QB57-k@OV zK__~lhtO&sD`I?#uI&YrLfrQ%z`68fS1vpcL3e&Sg1(RD$GfU5b)awNJtT@Ckv)Wsaq&@WDMZwRLpl*2g2TSdZuM_l5M zDq~U&y(LL%htO_P*N%(}6^eL0HR|1SyP{Y}`ZI1^ z+H_^TL12=$isO7-ryu>tz1^S+u|LeYBJ0xU+`00000NkvXXu0mjf#^WHu delta 2633 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 H-Y4OIMrzh^ literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/system_message_timer.imageset/system_message_timer@3x.png b/Signal/Images.xcassets/system_message_timer.imageset/system_message_timer@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..7622d0c1a62d97a02bc2053b48846c2b75c4e13e GIT binary patch literal 3121 zcmZ`*2{c=28xFOrGE@69(xA16*n`wsL8*zPji5z@1d%ieLdOu%&e;EIIz?$IV%Jn@ zYwXial~gNer)4sOq8+qFwSMJK=*;+?&OPTY-}AoD_q@-0?|aV8@bmSMlTnue0045H za5seD?kzl}Bm`Gm-=tT9n+O%*;R0ynYR(E4(qwo56#$UkD?CL2Ma8NBfEb8?MAOhd zhoM*!(KIxi6oxaU6Ul;X0KkC`6+9Agv``?O7!yl{(j7sY8BoEq5C(&Qn<=ztM-bY_ z59msw;DA=9mZoMPm<$jIbfAPsKoM?-KGOv&M-ZMyBSXR9goFgs1PfCVB@%3IXJ-dC zgMc9r6G4UvH8GYJN;iq6>TGTD*FJ7IDwaYZ(+H$kpm5*NFj5@N5d;zn{e5iJNh3u3 zqZCX1Y)fDeER2B7P0hexqT%R-f1wE@|4IwT{_Tn!M~T_=6pjVsVsJ!UER8DQnSW7E z(A&R>|5qeEl)NRj*~Bex4#LWz2pp9Z6DMo|DwaTlK^!&>?S%j7$QH|$L?lyiRH}dm zv-(Wgj_u4x|04sl`AcIvxRY>%LJ&9&71jka|17W_+nFEmC4ueWHiEGAP(K147lU>q z2pYQS!bV`@i-Da)S5gd#;!h66;)I25Qno=mvo~b|{!M0EU>h+U3#G<|Md7ftZEs8P z&Njb&f80s%HrN6D#cT(`mjLx4g%ctY-9l+N7{tun25M#vHG=@n1y^gRt)&BaN6xki zgb`N?E|f;1AW5Vc*rp4ja0#?9wccWGkAJ2*fQ3`EZK}3Lb`urMEKEkg{A>PUGDN2Q ze*gfFFKVA7o@Q>Sd&)C!1lG(Ov444kWruLpZ0UvSp-Y z%Y9zwz3NhYSbsPzD6^Z_m#sg<>;JwWqLNLRI-1-$dwz6^+y38i$Cb{NNt-vH#u6gA zg@qQ87pe1C-LoRRv>1C47k2x=)A_C+}%Ap z{B=)%BO;ka>zoNudUk_}qe%L8urC=6=T zc2zO`oo1o6%W#qZ%EgGk?l$Cn{hgey{XE>DPbowKy^HlA((b+fkI_BX`G(}LtJ9(W zwoBZgj8Au(=J?~HKZ#hGd8gL@3}syf+)VR#wtMBlkmLK1F|EJ2_YM!)Fu{!BUWX4w zMH9}m$d}8iggzs`vvVsS8(NwoEL9(7IZyhTT+$9pK^u!=4tVcU`lxrp{!ZV^_1ed@ zgM;%*c8G`5ur<0WzJtemE@hme3>@5vNCEP8zA~{1L_3 zk+c`m$cd|L%#lG!I?d*nfa45>rcV6;x%%VYe=L-?CoO(cs_4StjHu;2%?;5n5PQj( z1A3BL+HD4_czVaw)8G358_xBe`vtpjnvUkKX#{x1Dei8sje+J`2?P^9Gtz6 z^wb991GxrMXiQ#a1w+-_qObWSVWPK$jV%i*9j`pRkE`2!!?Ar7@!^AuOYjBM>`@09 z;(|!@bpACvr!11*4?(jRrMO}zf0cA4JkUPLSTs$3#PIZ0i@Sv=xmgTBWw91#Y=6(G z{n%RzVZ_5?P7j-lhgs(V{0Wm#;YXCNV=S<$TV*tC%iPGnrB| zZjIM@)A(aV#L@u1?PWY}~Q3`ihbP2nA3W>vSFQ zRnLKUApZ=E7<=j{&YXgW4gfGF0Dl3py*b-v@hx4t@NtySUP zy6tuDZ&n)Z*}=@)x?prs*9A2zt85jurld&l-5%F7=Pq>Hkl^hhC9ZcDcUOA3bV0(G zxySREK4;Da|9;URUBwvnL>iXS$*f7W0?j&ga>?yVYm0KvQcl2(3$MhCdFi8zGIP8% zH17}3yS+Pf^!^=nkAl7#jlvtYT%!)SK=SAOYxoO#c!kdC4RoE{aSkg1&BGhGwrgG5 zfXW`oS23Q_RmMS;(O$BXr`ENb*WRQ}1y3aT^O{h(B;tPMu434c*tvJL<>03olkRkn zupFI!)7*N@;}b~5KPuYR2JK1Hx6bCT)TXsGxH+#yKC;!BXiK9x!Z8QrZ;z&|pRSPA z#H}j(nR}M8uOwOJ4!r5diZmtdAK0Hflzr24;Z;FTX;_qZj{e7NqY)6kM8n7$NfsZ- z>;R7M@7UPg5B8i={$Pdl1ub)Xb)9#;Im9oIo2#IfCuT3ERmOvdw3+w1A7QH?{o>f) z_;?KCuui?9x|d0Cq^?}R96|+E*%E&~DFpNE6ynq!jgq@9Bghd{cIDcvabL9G%DyTS zpWgO0qw{TfPzlSf;lLcH)q|PZsl#utyI5Y)_Ihu3=#qSB1wbp$mN+;MGiJ$CwOlc6 zXMTXN&RtrcL4`%<)av#25#wuu{dw}X_m1wX8`VYKyexA@Nk3RMNHXn-W^;hV-4uiB z7IGi^{M%Dsy$dNfq_oK&Y%i-%9aB+iJU31JP^ObT`~c&^`ew>SzH}I3+)06al04x! zXj|-O=8#e~JzM>*u@a~0*Ug@sb(0xO@H=FqcDxkkap``?i;WjU#B>;%o(s3$tJpD9 zXK@*TX?EO*2PJG=6-hKxKfV9;Dx3GD_^qRQFHc+t(byVW1 zmD=|*p=C?v91S##^=@I{c7`RirJzc>pmndoi!Mm{tLuImdB$N|io7PU z!zXWRbGGi{bP7IZ2p>XnZ~p*}B}hi|8=A)&*~*kt)maSg_N zmy%eCvSRU`QrTMyOX3}=v1FrtTJH}q63-+1+Uk>%&GqLVV>XWG9^ADUOK({X{PwLg zKbWKRm6Ol%eMVezcJ=poKx4lI#wb(DH{A8(@N+(8kZdWMH!ZpVGmgUlH2r;yF<>%V2w^lpi<;HsXMd|v6mX?-X(Gs7c7{+3kj2o|M`E)8SrADBDCn&MGAmMZB3v?o0Sfko5zrf0CD1iG=jY@X z1s5bHr-B>?)`BF2t{QAjBra=^B#<cpt8_^$NwqUFFf`XSFw-?K3NbXZGBC3;v$WAiQ-kCJkc@LtYGO%#QAmD% zjvd$+xgf5Bv7Q-3C$c;NR|bQ0`sgL7f>fG|J!jXJHD=FU|?ePba4#v z;JrK5*F!W=Z5# z?2;Ep=K)_1r5A1mf_g44u7W(De?R_SKS#3tciKEL#oj+$uhSo^J5=sn7JGB*gq_JYyuDe= z*EY#2uI>4zmveaXgn1iRhW0mieYKvscG>>YFN~M>TU6zQhaczEImoPjx}N=P-@gg} zjAWeG3VXkP#d5Z>?BX=BuY1_KP2G-I>6$g4@9tm^+OF#Nu$bxVqCodx?ut@H*0t7K z>Y5(KHoh|XV!Hk?;|mejNYO|6EBd$=g&q`Kb4c04Sk`x~lij%z<_yD6h0pG1JLff> z+gr9^?h21Np+YlSX6<14qI9FhR-=8&(@)l{w_5Lcs(rS(sAYa5^FF=5Jk)NhJgAcJboFyt=akR{0Au7?!T^cg|b>d%y4h?swn2ImrqM z@-;+!iU0t>(BF?53f&3nbDchP-RdE~3Eg0lP+u>grqgm1S{R7@4oCn1X`()1K*1F= z0MJ8o!ssA9Fo4Ju^05q-FqVy#@kJ0C07x<-^vGv}43vz|6G(_MGFpQmLeJ_j4vo@4 zKrR_g4-7$h3&m`dGu8=xSBxXw_5RKxz zLeY+`#?wE@P+Z?>Xa`plg2f!jDMMWs#bHH2JGL5sU@ZadpcX;hdSVDi#^%wf9H^no zF7PDWnu*m!Zy`@8-Y;S>+3LbH6s^!|v_|H@$7Hk;T0|C;D3Qh{u$iFN+k)Pi=G*sT z9KmUYNw_u9BZ1`1i6xT91C$fgkR4z3uy3kFXJb8sQzU5L(3B-|>DRt4&ex0uZU zh2k)wkVnzD;H#G?N36>-Q#-#xCE?Ulq%~E`Bddu*GfP20%y;uoLF~!AGPsKu-wgbJbh{4SmCRmxP`}O z2DwAmuj@Mx?ipxKW6Eb~O5G@Z{x3U2BArgh55bo7n_#Jk3S?J6wXTD~Z_e&g&oAX& z={3EJr<__fvJUT%MIi_Tu} z+P`JN%V!!g9-kRLDpdYR3qd4UBc7hHo%=*DFuJQhTMJq~QidA5M0PWjah=%n&s3k8)m z25HHNR4>>B(R=>n*>Ly^Zs`|WqV5`b+8Y+xO)5UQVhWC@zjpl2G$lc4zJF$P!#x{W zcyrNhlR4CnEp2wnVm*pZRIS}ej=8(BqNTBQsnnyTE&i*?4q={4@oBTFyKDWqQJY5O?9K7^x+j>LlF^~+vC>m+)xoqM zhRnh(kY})tiC$F5oen(-gTF!WlAnfH?4-`ygC2O> zgl(AL8I#6;MDPSw_ocUY`(`Wib}pDvPT-~p1rhL1id(tvZ(BwK^xq(6SptPc#>{+k z>+E>b_nyMtO^e8=^|w0D#Sl9vdla^%4cDh_^0sjwro! znAdRnm`8Tt<~_Sdw~7Ed`rr%K@`F2&+Y(bchLBIjDsz8M$AueI;@Et=%;N5d&ZFPg zNndge=>Nt@oyx34j(CrR;y`iPeDrHzf3K(PK(6@A|4d81p1S|$xOZxz(VZRt;%>Cm z8xBq?yjW44<4UyNb#}&a^6sn38klkVQf|gv@~Jb{rHNL`R&v1f=-h(|_gV7?T~pxj zhU{_YiyhnNBX^V9Y2Cwp>Df;FR`zGAWJO~Mc(NxqzRTA7R)&6KYbYzI} z-h4GMlH736D01Op0i(B%K_EY@R&ezyYx;pPHtjaEQm<-nK|UNMc*Nd2j(L6umP5Cg hG)!npyD8JngiY3x;T@NGGWGu%f1e;~jaN+i{{i2NsC57U literal 0 HcmV?d00001 diff --git a/Signal/Images.xcassets/system_message_warning.imageset/system_message_warning@3x.png b/Signal/Images.xcassets/system_message_warning.imageset/system_message_warning@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..ec37d57524b7ccd7f6582108f4617d78c6deb28f GIT binary patch literal 3015 zcmZ`*2UJtp7ELG#QidjxA`l?{!9ofM3^9ZjnuuZqO%w+r2@ps#2@nuziUOj5g7T$< z4*sE|FoJ$SDZxfl2cRlh1PATCd!5_P+b<^WItO#k=iyRFKt_1pojF z&Q3VI@a`fyWkAB~Py53@3U5FT-q99N+O~C6xY)#UB60u#IaSdK1YFNl2LPn>sqO?W z!F35r=*?tI=g@pwI zX^b#7HWDI?IH3$KiD$&%7_4vd=RPW=m)gA<7_7a3tb;GzyRU4>VEcA8BNtzg)3`*t9iIWFG{DMxj#}T#k^3`mUU? zw|^1;uSgz=wJx^S#C2~NQRQeng~Ox;iCW;npmMRsm^DKi!+&>Von^%#Dy{Mo43Klo=XnhBgt_z5ydvfhc3g zrjWQywmXwa!>+lYi(wEOav{2OB=Z`Cd-{<)!;|t2@hjL>ws&nigk; zONEisb?u0oiJ$B`Zgp%vSM1+Z4AZ@M&LVbUhl|PcMQj$O$kH#1(_XXmw2x1mdNvR; zK3lgmc6+Yw`AruGqI9J!SOs@|4?t2tbxr7~gwISdVHb6wRK}6opBD9$ko`qdbQ;V~FxcBjaE#7KGm5U3Id6#LK6YY|9{L~A z{BkKe(#JLXbjFKwB> ze;vM~c55dC98tc@i{bpf-^N`jUIOv>DBVr(^1c?=bq0HD3iyo- zY2LAhX~Q9nuK%i0rhm=fj2Zw7^5OPf9*Z%cRl0emJeEUUsv+F zfi)e&N?oGVa zZ4qzuGis7Ui|-E-906!Mn7nb${Nw6xfI}({o!Vi0wD0xpsfcs-H%sNxy8IGVuc+_K zZ!{$%plv}x9Zj;LUb`cFyOF2b0NPn}}qoh5~6O@UqH< z`wGctU(KYn`OR7CEH3LE?oD0woH}$fuY6*nvN<#h+>X(Vx2(B%LH(VJfww>^cQ|deGW_DP#R3$ohgI8vPk1yq^lC(_8*Fr5 zd3!R0*z^Xw)nCig+)Sb;<#WAceG;UtU~+LDrg-dVT9TIeU6tF6?f@Izm7|TyS=jfD zHW?R_w5>8QJ=r6#uEtDDBipX!3?Sc5L^gH$CQheKUf|8OX-PZ?@H$62pV2!W)l}MB zBKWaC-+I>SdQz#`uG85Qp^xXB!}~(fN^ft|WfJ}XB5Ss%ZRPIS>7@4qQ|YXtMoV`S z${kwS_oT#ph6>E#-)L&$TOaXSxX9OE+`d?B8g4u?dN86Uw^|d#3p;Qnz}vGWu*pHcR}a~Nn9l)Exh@`2)~tun8kcrvRi;%0qEmsUIwVlNeRuMa=-bfj&? zMnDnhLC0+$G>3+1M+Vh(S;e614T-b^ZPi9b&m zxak)g;B^LZ@LI6reGOtok1IrHdIBs#-G2A=SgqTc+qatKqCN0Wf9xETOXYM1L%&jg z{a4=c)lYnw;B>BMLd(Bj020BEDa?3xlgB%fJ)lL_hoj+NB?N;%FuH#!&K3P#JKOKa JmD+m8{15q$?GOL} literal 0 HcmV?d00001 diff --git a/Signal/src/Models/OWSMessagesBubblesSizeCalculator.m b/Signal/src/Models/OWSMessagesBubblesSizeCalculator.m index 1ed99b553..524574816 100644 --- a/Signal/src/Models/OWSMessagesBubblesSizeCalculator.m +++ b/Signal/src/Models/OWSMessagesBubblesSizeCalculator.m @@ -9,7 +9,9 @@ #import "OWSUnreadIndicatorCell.h" #import "TSGenericAttachmentAdapter.h" #import "TSMessageAdapter.h" +#import "TSUnreadIndicatorInteraction.h" #import "UIFont+OWS.h" +#import "UIView+OWS.h" #import "tgmath.h" // generic math allows fmax to handle CGFLoat correctly on 32 & 64bit. #import #import @@ -49,22 +51,59 @@ NS_ASSUME_NONNULL_BEGIN atIndexPath:(NSIndexPath *)indexPath withLayout:(JSQMessagesCollectionViewFlowLayout *)layout { + // DDLogError(@"----- ?? %@", + // [messageData class]); + if ([messageData isKindOfClass:[TSMessageAdapter class]]) { TSMessageAdapter *message = (TSMessageAdapter *)messageData; - if (message.messageType == TSErrorMessageAdapter) { - return [OWSSystemMessageCell cellSizeForInteraction:((TSMessageAdapter *)messageData).interaction - collectionViewWidth:layout.collectionView.bounds.size.width]; - } else if (message.messageType == TSInfoMessageAdapter || message.messageType == TSErrorMessageAdapter) { - return [self messageBubbleSizeForInfoMessageData:messageData atIndexPath:indexPath withLayout:layout]; - } else if (message.messageType == TSUnreadIndicatorAdapter) { - return [OWSUnreadIndicatorCell - cellSizeForInteraction:(TSUnreadIndicatorInteraction *)((TSMessageAdapter *)messageData).interaction - collectionViewWidth:layout.collectionView.bounds.size.width]; - } - } - if ([messageData isKindOfClass:[OWSCall class]]) { - return [self messageBubbleSizeForCallData:messageData atIndexPath:indexPath withLayout:layout]; + // DDLogError(@"----- ???? %d", (int) message.messageType); + + switch (message.messageType) { + case TSCallAdapter: + case TSInfoMessageAdapter: + case TSErrorMessageAdapter: { + id cacheKey = [self cacheKeyForMessageData:messageData]; + TSInteraction *interaction = ((TSMessageAdapter *)messageData).interaction; + return [self sizeForSystemMessage:interaction cacheKey:cacheKey layout:layout]; + } + case TSUnreadIndicatorAdapter: { + id cacheKey = [self cacheKeyForMessageData:messageData]; + + TSUnreadIndicatorInteraction *interaction + = (TSUnreadIndicatorInteraction *)((TSMessageAdapter *)messageData).interaction; + + NSValue *cachedSize = [self.cache objectForKey:cacheKey]; + if (cachedSize != nil) { + // DDLogError(@"----- cache hit[%@,%@], %@ %@", + // [interaction class], + // cacheKey, + // NSStringFromCGSize([cachedSize CGSizeValue]), + // interaction.description); + return [cachedSize CGSizeValue]; + } + + CGSize result = [OWSUnreadIndicatorCell cellSizeForInteraction:interaction + collectionViewWidth:layout.collectionView.width]; + + [self.cache setObject:[NSValue valueWithCGSize:result] forKey:cacheKey]; + + // DDLogError(@"----- cache miss[%@,%@], %@ %@", + // [interaction class], + // cacheKey, + // NSStringFromCGSize(result), + // interaction.description); + + return result; + } + default: + // TODO: we need to examine the other cases. + break; + } + } else if ([messageData isKindOfClass:[OWSCall class]]) { + id cacheKey = [self cacheKeyForMessageData:messageData]; + TSInteraction *interaction = ((OWSCall *)messageData).interaction; + return [self sizeForSystemMessage:interaction cacheKey:cacheKey layout:layout]; } // BEGIN HACK iOS10EmojiBug see: https://github.com/WhisperSystems/Signal-iOS/issues/1368 @@ -79,6 +118,37 @@ NS_ASSUME_NONNULL_BEGIN } } +- (CGSize)sizeForSystemMessage:(TSInteraction *)interaction + cacheKey:(id)cacheKey + layout:(JSQMessagesCollectionViewFlowLayout *)layout +{ + OWSAssert(interaction); + OWSAssert(cacheKey); + + NSValue *cachedSize = [self.cache objectForKey:cacheKey]; + if (cachedSize != nil) { + // DDLogError(@"----- cache hit[%@,%@], %@ %@", + // [interaction class], + // cacheKey, + // NSStringFromCGSize([cachedSize CGSizeValue]), + // interaction.description); + return [cachedSize CGSizeValue]; + } + + CGSize result = + [OWSSystemMessageCell cellSizeForInteraction:interaction collectionViewWidth:layout.collectionView.width]; + + [self.cache setObject:[NSValue valueWithCGSize:result] forKey:cacheKey]; + + // DDLogError(@"----- cache miss[%@,%@], %@ %@", + // [interaction class], + // cacheKey, + // NSStringFromCGSize(result), + // interaction.description); + + return result; +} + /** * Emoji sizing bug only affects iOS10. Unfortunately the "fix" for emoji font breaks some other fonts, so it's * important @@ -137,120 +207,6 @@ NS_ASSUME_NONNULL_BEGIN return CGSizeMake(superSize.width, superSize.height + (CGFloat)1.5 * lines); } - -- (CGSize)messageBubbleSizeForInfoMessageData:(id)messageData - atIndexPath:(NSIndexPath *)indexPath - withLayout:(JSQMessagesCollectionViewFlowLayout *)layout -{ - id cacheKey = [self cacheKeyForMessageData:messageData]; - - NSValue *cachedSize = [self.cache objectForKey:cacheKey]; - if (cachedSize != nil) { - return [cachedSize CGSizeValue]; - } - - CGSize finalSize = CGSizeZero; - - if ([messageData isMediaMessage]) { - finalSize = [[messageData media] mediaViewDisplaySize]; - } else { - /////////////////// - // BEGIN InfoMessage sizing HACK - // Braindead, and painstakingly produced. - // If you want to change, check for clipping / excess space on 1, 2, and 3 line messages with short and long - // words very near the edge. - -// CGSize avatarSize = [self jsq_avatarSizeForMessageData:messageData withLayout:layout]; -// // from the cell xibs, there is a 2 point space between avatar and bubble -// CGFloat spacingBetweenAvatarAndBubble = 2.0f; -// CGFloat horizontalContainerInsets = layout.messageBubbleTextViewTextContainerInsets.left + layout.messageBubbleTextViewTextContainerInsets.right; -// CGFloat horizontalFrameInsets = layout.messageBubbleTextViewFrameInsets.left + layout.messageBubbleTextViewFrameInsets.right; -// CGFloat horizontalInsetsTotal = horizontalContainerInsets + horizontalFrameInsets + spacingBetweenAvatarAndBubble; -// CGFloat maximumTextWidth = [self textBubbleWidthForLayout:layout] - avatarSize.width - layout.messageBubbleLeftRightMargin - horizontalInsetsTotal; - - // The full layout width, less the textView margins from xib. -// CGFloat horizontalInsetsTotal = 12.0; cropped 3rd line - CGFloat horizontalInsetsTotal = 50.0; - CGFloat maximumTextWidth = [self textBubbleWidthForLayout:layout] - horizontalInsetsTotal; - - CGRect stringRect = [[messageData text] - boundingRectWithSize:CGSizeMake(maximumTextWidth, CGFLOAT_MAX) - options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) - attributes:@{ - NSFontAttributeName : [UIFont ows_dynamicTypeBodyFont] - } // Hack to use a slightly larger than actual font, because I'm seeing messages with higher line count get clipped. - context:nil]; - // END InfoMessage sizing HACK - //////////////////// - - CGSize stringSize = CGRectIntegral(stringRect).size; - - CGFloat verticalContainerInsets = layout.messageBubbleTextViewTextContainerInsets.top - + layout.messageBubbleTextViewTextContainerInsets.bottom; - - CGFloat verticalFrameInsets - = layout.messageBubbleTextViewFrameInsets.top + layout.messageBubbleTextViewFrameInsets.bottom; - /////////////////// - // BEGIN InfoMessage sizing HACK - - CGFloat topIconPortrusion = 28; - - verticalFrameInsets += topIconPortrusion; - - // END InfoMessage sizing HACK - /////////////////// - - // add extra 2 points of space (`self.additionalInset`), because `boundingRectWithSize:` is slightly off - // not sure why. magix. (shrug) if you know, submit a PR - CGFloat verticalInsets = verticalContainerInsets + verticalFrameInsets + self.additionalInset; - - // same as above, an extra 2 points of magix - CGFloat finalWidth - = MAX(stringSize.width + horizontalInsetsTotal, self.minimumBubbleWidth) + self.additionalInset; - - finalSize = CGSizeMake(finalWidth, stringSize.height + verticalInsets); - } - - [self.cache setObject:[NSValue valueWithCGSize:finalSize] forKey:cacheKey]; - - return finalSize; -} - -- (CGSize)messageBubbleSizeForCallData:(id)messageData - atIndexPath:(NSIndexPath *)indexPath - withLayout:(JSQMessagesCollectionViewFlowLayout *)layout -{ - id cacheKey = [self cacheKeyForMessageData:messageData]; - - NSValue *cachedSize = [self.cache objectForKey:cacheKey]; - if (cachedSize != nil) { - return [cachedSize CGSizeValue]; - } - - CGFloat horizontalInsetsTotal = 0.0; - CGFloat maximumTextWidth = [self textBubbleWidthForLayout:layout] - horizontalInsetsTotal; - - CGRect stringRect = [[messageData text] - boundingRectWithSize:CGSizeMake(maximumTextWidth, CGFLOAT_MAX) - options:(NSStringDrawingUsesLineFragmentOrigin | NSStringDrawingUsesFontLeading) - attributes:@{ - NSFontAttributeName : [UIFont ows_dynamicTypeBodyFont] - } // Hack to use a slightly larger than actual font, because I'm seeing messages with higher line - // count get clipped. - context:nil]; - - CGSize stringSize = CGRectIntegral(stringRect).size; - - CGFloat verticalInsets = 0; - CGFloat finalWidth = maximumTextWidth + horizontalInsetsTotal; - - CGSize finalSize = CGSizeMake(finalWidth, stringSize.height + verticalInsets); - - [self.cache setObject:[NSValue valueWithCGSize:finalSize] forKey:cacheKey]; - - return finalSize; -} - - (id)cacheKeyForMessageData:(id)messageData { OWSAssert(messageData); diff --git a/Signal/src/ViewControllers/ConversationView/MessagesViewController.m b/Signal/src/ViewControllers/ConversationView/MessagesViewController.m index 54d6beb8e..fe28c5c71 100644 --- a/Signal/src/ViewControllers/ConversationView/MessagesViewController.m +++ b/Signal/src/ViewControllers/ConversationView/MessagesViewController.m @@ -1460,16 +1460,18 @@ typedef enum : NSUInteger { JSQMessagesCollectionViewCell *cell; switch (message.messageType) { case TSCallAdapter: { - OWSCall *call = (OWSCall *)message; - cell = [self loadCallCellForCall:call atIndexPath:indexPath]; + // OWSCall *call = (OWSCall *)message; + // cell = [self loadCallCellForCall:call atIndexPath:indexPath]; + cell = [self loadSystemMessageCell:indexPath interaction:message.interaction]; break; } case TSInfoMessageAdapter: { - cell = [self loadInfoMessageCellForMessage:(TSMessageAdapter *)message atIndexPath:indexPath]; + // TODO: There's more work to here. + cell = [self loadSystemMessageCell:indexPath interaction:message.interaction]; break; } case TSErrorMessageAdapter: { - cell = [self loadErrorMessageCell:indexPath interaction:message.interaction]; + cell = [self loadSystemMessageCell:indexPath interaction:message.interaction]; break; } case TSIncomingMessageAdapter: { @@ -1573,38 +1575,38 @@ typedef enum : NSUInteger { return cell; } -- (OWSCallCollectionViewCell *)loadCallCellForCall:(OWSCall *)call atIndexPath:(NSIndexPath *)indexPath -{ - OWSCallCollectionViewCell *callCell = - [self.collectionView dequeueReusableCellWithReuseIdentifier:[OWSCallCollectionViewCell cellReuseIdentifier] - forIndexPath:indexPath]; - - NSString *text = call.date != nil ? [call text] : call.senderDisplayName; - NSString *allText = call.date != nil ? [text stringByAppendingString:[call dateText]] : text; - - UIFont *boldFont = [UIFont fontWithName:@"HelveticaNeue-Medium" size:12.0f]; - NSMutableAttributedString *attributedText = - [[NSMutableAttributedString alloc] initWithString:allText attributes:@{ NSFontAttributeName : boldFont }]; - if ([call date] != nil) { - // Not a group meta message - UIFont *regularFont = [UIFont fontWithName:@"HelveticaNeue-Light" size:12.0f]; - const NSRange range = NSMakeRange([text length], [[call dateText] length]); - [attributedText setAttributes:@{ NSFontAttributeName : regularFont } range:range]; - } - callCell.textView.text = nil; - callCell.textView.attributedText = attributedText; - - callCell.textView.textAlignment = NSTextAlignmentCenter; - callCell.textView.textColor = [UIColor ows_materialBlueColor]; - callCell.layer.shouldRasterize = YES; - callCell.layer.rasterizationScale = [UIScreen mainScreen].scale; - - // Disable text selectability. Specifying this in prepareForReuse/awakeFromNib was not sufficient. - callCell.textView.userInteractionEnabled = NO; - callCell.textView.selectable = NO; - - return callCell; -} +//- (OWSCallCollectionViewCell *)loadCallCellForCall:(OWSCall *)call atIndexPath:(NSIndexPath *)indexPath +//{ +// OWSCallCollectionViewCell *callCell = +// [self.collectionView dequeueReusableCellWithReuseIdentifier:[OWSCallCollectionViewCell cellReuseIdentifier] +// forIndexPath:indexPath]; +// +// NSString *text = call.date != nil ? [call text] : call.senderDisplayName; +// NSString *allText = call.date != nil ? [text stringByAppendingString:[call dateText]] : text; +// +// UIFont *boldFont = [UIFont fontWithName:@"HelveticaNeue-Medium" size:12.0f]; +// NSMutableAttributedString *attributedText = +// [[NSMutableAttributedString alloc] initWithString:allText attributes:@{ NSFontAttributeName : boldFont }]; +// if ([call date] != nil) { +// // Not a group meta message +// UIFont *regularFont = [UIFont fontWithName:@"HelveticaNeue-Light" size:12.0f]; +// const NSRange range = NSMakeRange([text length], [[call dateText] length]); +// [attributedText setAttributes:@{ NSFontAttributeName : regularFont } range:range]; +// } +// callCell.textView.text = nil; +// callCell.textView.attributedText = attributedText; +// +// callCell.textView.textAlignment = NSTextAlignmentCenter; +// callCell.textView.textColor = [UIColor ows_materialBlueColor]; +// callCell.layer.shouldRasterize = YES; +// callCell.layer.rasterizationScale = [UIScreen mainScreen].scale; +// +// // Disable text selectability. Specifying this in prepareForReuse/awakeFromNib was not sufficient. +// callCell.textView.userInteractionEnabled = NO; +// callCell.textView.selectable = NO; +// +// return callCell; +//} - (OWSDisplayedMessageCollectionViewCell *)loadDisplayedMessageCollectionViewCellForIndexPath:(NSIndexPath *)indexPath { @@ -1620,38 +1622,70 @@ typedef enum : NSUInteger { return messageCell; } -- (OWSDisplayedMessageCollectionViewCell *)loadInfoMessageCellForMessage:(TSMessageAdapter *)infoMessage - atIndexPath:(NSIndexPath *)indexPath -{ - OWSDisplayedMessageCollectionViewCell *infoCell = - [self loadDisplayedMessageCollectionViewCellForIndexPath:indexPath]; - - // HACK this will get called when we get a new info message, but there's gotta be a better spot for this. - OWSDisappearingMessagesConfiguration *configuration = - [OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:self.thread.uniqueId]; - [self setBarButtonItemsForDisappearingMessagesConfiguration:configuration]; - - infoCell.textView.text = [infoMessage text]; - - // Disable text selectability. Specifying this in prepareForReuse/awakeFromNib was not sufficient. - infoCell.textView.userInteractionEnabled = NO; - infoCell.textView.selectable = NO; - - infoCell.messageBubbleContainerView.layer.borderColor = [[UIColor ows_infoMessageBorderColor] CGColor]; - if (infoMessage.infoMessageType == TSInfoMessageTypeDisappearingMessagesUpdate) { - infoCell.headerImageView.image = [UIImage imageNamed:@"ic_timer"]; - infoCell.headerImageView.backgroundColor = [UIColor whiteColor]; - // Lighten up the broad stroke header icon to match the perceived color of the border. - infoCell.headerImageView.tintColor = [UIColor ows_infoMessageBorderColor]; - } else { - infoCell.headerImageView.image = [UIImage imageNamed:@"warning_white"]; - } - - - return infoCell; -} - -- (OWSSystemMessageCell *)loadErrorMessageCell:(NSIndexPath *)indexPath interaction:(TSInteraction *)interaction +//- (OWSDisplayedMessageCollectionViewCell *)loadInfoMessageCellForMessage:(TSMessageAdapter *)infoMessage +// atIndexPath:(NSIndexPath *)indexPath +//{ +// OWSDisplayedMessageCollectionViewCell *infoCell = +// [self loadDisplayedMessageCollectionViewCellForIndexPath:indexPath]; +// +// // HACK this will get called when we get a new info message, but there's gotta be a better spot for this. +// OWSDisappearingMessagesConfiguration *configuration = +// [OWSDisappearingMessagesConfiguration fetchObjectWithUniqueID:self.thread.uniqueId]; +// [self setBarButtonItemsForDisappearingMessagesConfiguration:configuration]; +// +// infoCell.textView.text = [infoMessage text]; +// +// // Disable text selectability. Specifying this in prepareForReuse/awakeFromNib was not sufficient. +// infoCell.textView.userInteractionEnabled = NO; +// infoCell.textView.selectable = NO; +// +// infoCell.messageBubbleContainerView.layer.borderColor = [[UIColor ows_infoMessageBorderColor] CGColor]; +// if (infoMessage.infoMessageType == TSInfoMessageTypeDisappearingMessagesUpdate) { +// infoCell.headerImageView.image = [UIImage imageNamed:@"ic_timer"]; +// infoCell.headerImageView.backgroundColor = [UIColor whiteColor]; +// // Lighten up the broad stroke header icon to match the perceived color of the border. +// infoCell.headerImageView.tintColor = [UIColor ows_infoMessageBorderColor]; +// } else { +// infoCell.headerImageView.image = [UIImage imageNamed:@"warning_white"]; +// } +// +// +// return infoCell; +//} + +//- (OWSSystemMessageCell *)loadErrorMessageCell:(NSIndexPath *)indexPath interaction:(TSInteraction *)interaction +//// ForMessage:(TSMessageAdapter *)errorMessage +//// atIndexPath:(NSIndexPath *)indexPath +//{ +// OWSAssert(indexPath); +// OWSAssert(interaction); +// // OWSAssert([interaction isKindOfClass:[TSUnreadIndicatorInteraction class]]); +// +// // TSUnreadIndicatorInteraction *unreadIndicator = (TSUnreadIndicatorInteraction *)interaction; +// +// OWSSystemMessageCell *cell = +// [self.collectionView dequeueReusableCellWithReuseIdentifier:[OWSSystemMessageCell cellReuseIdentifier] +// forIndexPath:indexPath]; +// cell.interaction = interaction; +// [cell configure]; +// +// return cell; +// +// // OWSDisplayedMessageCollectionViewCell *errorCell = +// // [self loadDisplayedMessageCollectionViewCellForIndexPath:indexPath]; +// // errorCell.textView.text = [errorMessage text]; +// // +// // // Disable text selectability. Specifying this in prepareForReuse/awakeFromNib was not sufficient. +// // errorCell.textView.userInteractionEnabled = NO; +// // errorCell.textView.selectable = NO; +// // +// // errorCell.messageBubbleContainerView.layer.borderColor = [[UIColor ows_errorMessageBorderColor] CGColor]; +// // errorCell.headerImageView.image = [UIImage imageNamed:@"error_white"]; +// // +// // return errorCell; +//} + +- (OWSSystemMessageCell *)loadSystemMessageCell:(NSIndexPath *)indexPath interaction:(TSInteraction *)interaction // ForMessage:(TSMessageAdapter *)errorMessage // atIndexPath:(NSIndexPath *)indexPath { @@ -3930,7 +3964,8 @@ typedef enum : NSUInteger { // TODO: TSInteraction *interaction = [self interactionAtIndexPath:indexPath]; return ([interaction isKindOfClass:[TSUnreadIndicatorInteraction class]] || - [interaction isKindOfClass:[TSErrorMessage class]]); + [interaction isKindOfClass:[TSInfoMessage class]] || [interaction isKindOfClass:[TSErrorMessage class]] || + [interaction isKindOfClass:[TSCall class]]); } #pragma mark - Class methods diff --git a/Signal/src/ViewControllers/SignalsViewController.m b/Signal/src/ViewControllers/SignalsViewController.m index ac4a23fc6..ef90c011a 100644 --- a/Signal/src/ViewControllers/SignalsViewController.m +++ b/Signal/src/ViewControllers/SignalsViewController.m @@ -202,6 +202,10 @@ NSString *const SignalsViewControllerSegueShowIncomingCall = @"ShowIncomingCallS object:nil]; [self updateBarButtonItems]; + + dispatch_async(dispatch_get_main_queue(), ^{ + [self tableView:self.tableView didSelectRowAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; + }); } - (void)updateBarButtonItems { diff --git a/Signal/src/environment/NotificationsManager.m b/Signal/src/environment/NotificationsManager.m index 2e72eadbc..7d009d9cf 100644 --- a/Signal/src/environment/NotificationsManager.m +++ b/Signal/src/environment/NotificationsManager.m @@ -21,6 +21,8 @@ @property (nonatomic) SystemSoundID newMessageSound; @property (nonatomic, readonly) NSMutableDictionary *currentNotifications; @property (nonatomic, readonly) NotificationType notificationPreviewType; +//@property (nonatomic, readonly) NSMutableArray *recentErrorTimestamps; +//@property (nonatomic, readonly) NSMutableArray *recentIncomingMessageTimestamps; @end @@ -36,6 +38,8 @@ } _currentNotifications = [NSMutableDictionary new]; + // _recentErrorTimestamps = [NSMutableArray new]; + // _recentIncomingMessageTimestamps = [NSMutableArray new]; NSURL *newMessageURL = [[NSBundle mainBundle] URLForResource:@"NewMessage" withExtension:@"aifc"]; AudioServicesCreateSystemSoundID((__bridge CFURLRef)newMessageURL, &_newMessageSound); @@ -258,6 +262,18 @@ } } +//- (BOOL)addNotificationTimestamp:(NSMutableArray *)timestamps +//{ +// OWSAssert(timestamps); +// +// [timestamps addObject:[NSDate date]]; +// +// // Cull old timestamps. +// const CGFloat kThrottlingDuration = 5.f; +//} +//_recentErrorTimestamps = [NSMutableArray new]; +//_recentIncomingMessageTimestamps = [NSMutableArray new]; + #pragma mark - Util - (NotificationType)notificationPreviewType diff --git a/Signal/src/views/OWSSystemMessageCell.m b/Signal/src/views/OWSSystemMessageCell.m index 5163aca2a..052d0cffa 100644 --- a/Signal/src/views/OWSSystemMessageCell.m +++ b/Signal/src/views/OWSSystemMessageCell.m @@ -9,7 +9,9 @@ #import "UIFont+OWS.h" #import "UIView+OWS.h" #import +#import #import +#import @interface OWSSystemMessageCell () @@ -75,7 +77,7 @@ // [self.imageView addRedBorder]; // [self addRedBorder]; - UIColor *contentColor = [UIColor ows_darkGrayColor]; + UIColor *contentColor = [self colorForInteraction:self.interaction]; UIImage *icon = [self iconForInteraction:self.interaction]; self.imageView.image = [icon imageWithRenderingMode:UIImageRenderingModeAlwaysTemplate]; // self.imageView.tintColor = [UIColor colorWithRGBHex:0x505050]; @@ -84,15 +86,114 @@ self.titleLabel.text = [OWSSystemMessageCell titleForInteraction:self.interaction]; self.titleLabel.textColor = contentColor; + // DDLogError(@"----- %@ %@", + // [self.interaction class], + // self.interaction.description); + [self setNeedsLayout]; + // [self addRedBorder]; +} + +- (UIColor *)colorForInteraction:(TSInteraction *)interaction +{ + // UIImage *result = nil; + + if ([interaction isKindOfClass:[TSErrorMessage class]]) { + switch (((TSErrorMessage *)self.interaction).errorType) { + case TSErrorMessageInvalidKeyException: + return [UIColor ows_yellowColor]; + case TSErrorMessageNonBlockingIdentityChange: + case TSErrorMessageWrongTrustedIdentityKey: + case TSErrorMessageMissingKeyId: + // result = [UIImage imageNamed:@"system_message_security"]; + break; + case TSErrorMessageNoSession: + case TSErrorMessageInvalidMessage: + case TSErrorMessageDuplicateMessage: + case TSErrorMessageInvalidVersion: + case TSErrorMessageUnknownContactBlockOffer: + // result = [UIImage imageNamed:@"system_message_warning"]; + break; + } + } else if ([interaction isKindOfClass:[TSInfoMessage class]]) { + switch (((TSInfoMessage *)self.interaction).messageType) { + case TSInfoMessageUserNotRegistered: + // result = [UIImage imageNamed:@"system_message_warning"]; + break; + case TSInfoMessageTypeSessionDidEnd: + case TSInfoMessageTypeUnsupportedMessage: + case TSInfoMessageAddToContactsOffer: + // result = [UIImage imageNamed:@"system_message_info"]; + break; + case TSInfoMessageTypeGroupUpdate: + case TSInfoMessageTypeGroupQuit: + // TODO: + // result = [UIImage imageNamed:@"system_message_info"]; + break; + case TSInfoMessageTypeDisappearingMessagesUpdate: + // result = [UIImage imageNamed:@"system_message_timer"]; + break; + } + } else if ([interaction isKindOfClass:[TSCall class]]) { + // TODO: + // result = [UIImage imageNamed:@"system_message_call"]; + } else { + OWSFail(@"Unknown interaction type"); + return nil; + } + // return [UIColor ows_darkGrayColor]; + return [UIColor colorWithRGBHex:0x505050]; } - (UIImage *)iconForInteraction:(TSInteraction *)interaction { UIImage *result = nil; + if ([interaction isKindOfClass:[TSErrorMessage class]]) { + // DDLogError(@"----- %@ %@: %d", + // [self.interaction class], + // self.interaction.description, + // (int) ((TSErrorMessage *) self.interaction).errorType); + switch (((TSErrorMessage *)self.interaction).errorType) { + case TSErrorMessageInvalidKeyException: + case TSErrorMessageNonBlockingIdentityChange: + case TSErrorMessageWrongTrustedIdentityKey: + case TSErrorMessageMissingKeyId: + result = [UIImage imageNamed:@"system_message_security"]; + break; + case TSErrorMessageNoSession: + case TSErrorMessageInvalidMessage: + case TSErrorMessageDuplicateMessage: + case TSErrorMessageInvalidVersion: + case TSErrorMessageUnknownContactBlockOffer: + result = [UIImage imageNamed:@"system_message_warning"]; + break; + } + } else if ([interaction isKindOfClass:[TSInfoMessage class]]) { + // DDLogError(@"----- %@ %@: %d", + // [self.interaction class], + // self.interaction.description, + // (int) ((TSInfoMessage *) self.interaction).messageType); + switch (((TSInfoMessage *)self.interaction).messageType) { + case TSInfoMessageUserNotRegistered: + result = [UIImage imageNamed:@"system_message_warning"]; + break; + case TSInfoMessageTypeSessionDidEnd: + case TSInfoMessageTypeUnsupportedMessage: + case TSInfoMessageAddToContactsOffer: + result = [UIImage imageNamed:@"system_message_info"]; + break; + case TSInfoMessageTypeGroupUpdate: + case TSInfoMessageTypeGroupQuit: + result = [UIImage imageNamed:@"system_message_group"]; + break; + case TSInfoMessageTypeDisappearingMessagesUpdate: + result = [UIImage imageNamed:@"system_message_timer"]; + break; + } + } else if ([interaction isKindOfClass:[TSCall class]]) { // TODO: - result = [UIImage imageNamed:@"system_message_security"]; + result = [UIImage imageNamed:@"system_message_call"]; } else { OWSFail(@"Unknown interaction type"); return nil; @@ -109,6 +210,20 @@ if ([interaction isKindOfClass:[TSErrorMessage class]]) { // TODO: Should we move the copy generation into this view? return interaction.description; + } else if ([interaction isKindOfClass:[TSInfoMessage class]]) { + // TODO: Should we move the copy generation into this view? + return interaction.description; + } else if ([interaction isKindOfClass:[TSCall class]]) { + // switch (((TSCall *) self.interaction).callType) { + // case <#constant#>: + // <#statements#> + // break; + // + // default: + // break; + // } + // TODO: Should we move the copy generation into this view? + return interaction.description; } else { OWSFail(@"Unknown interaction type"); return nil; @@ -123,51 +238,6 @@ return [UIFont ows_regularFontWithSize:13.f]; } -//+ (UIFont *)subtitleFont -//{ -// return [UIFont ows_regularFontWithSize:12.f]; -//} - -//+ (NSString *)subtitleForInteraction:(TSUnreadIndicatorInteraction *)interaction -//{ -// if (!interaction.hasMoreUnseenMessages) { -// return nil; -// } -// NSString *subtitleFormat = (interaction.missingUnseenSafetyNumberChangeCount > 0 -// ? NSLocalizedString(@"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES_FORMAT", -// @"Messages that indicates that there are more unseen messages that be revealed by tapping the 'load -// " -// @"earlier messages' button. Embeds {{the name of the 'load earlier messages' button}}") -// : NSLocalizedString( -// @"MESSAGES_VIEW_UNREAD_INDICATOR_HAS_MORE_UNSEEN_MESSAGES_AND_SAFETY_NUMBER_CHANGES_FORMAT", -// @"Messages that indicates that there are more unseen messages including safety number changes that " -// @"be revealed by tapping the 'load earlier messages' button. Embeds {{the name of the 'load earlier -// " -// @"messages' button}}.")); -// NSString *loadMoreButtonName = [NSBundle jsq_localizedStringForKey:@"load_earlier_messages"]; -// return [NSString stringWithFormat:subtitleFormat, loadMoreButtonName]; -//} - -//+ (CGFloat)subtitleHMargin -//{ -// return 20.f; -//} -// -//+ (CGFloat)subtitleVSpacing -//{ -// return 3.f; -//} -// -//+ (CGFloat)titleInnerHMargin -//{ -// return 10.f; -//} -// -//+ (CGFloat)titleVMargin -//{ -// return 5.5f; -//} - + (CGFloat)hMargin { return 30.f; @@ -185,52 +255,21 @@ + (CGFloat)hSpacing { - return 10.f; + return 8.f; } + (CGFloat)iconSize { - return 30.f; + return 25.f; } - (void)layoutSubviews { [super layoutSubviews]; - // [self.titleLabel sizeToFit]; - // - // // It's a bit of a hack, but we use a view that extends _outside_ the cell's bounds - // // to draw its background, since we want the background to extend to the edges of the - // // collection view. - // // - // // This layout logic assumes that the cell insets are symmetrical and can be deduced - // // from the cell frame. - // CGRect bannerViewFrame = CGRectMake(-self.left, - // round(OWSSystemMessageCell.topVMargin), - // round(self.width + self.left * 2.f), - // round(self.titleLabel.height + OWSSystemMessageCell.titleVMargin * 2.f)); - // self.bannerView.frame = [self convertRect:bannerViewFrame toView:self.contentView]; - // - // // The highlights should be 1px (not 1pt), so adapt their thickness to - // // the device resolution. - // CGFloat kHighlightThickness = 1.f / [UIScreen mainScreen].scale; - // self.bannerTopHighlightView.frame = CGRectMake(0, 0, self.bannerView.width, kHighlightThickness); - // self.bannerBottomHighlightView1.frame - // = CGRectMake(0, self.bannerView.height - kHighlightThickness * 2.f, self.bannerView.width, - // kHighlightThickness); - // self.bannerBottomHighlightView2.frame - // = CGRectMake(0, self.bannerView.height - kHighlightThickness * 1.f, self.bannerView.width, - // kHighlightThickness); - // - // [self.titleLabel centerOnSuperview]; - CGFloat maxTitleWidth = (self.contentView.width - ([OWSSystemMessageCell hMargin] * 2.f + [OWSSystemMessageCell hSpacing] + [OWSSystemMessageCell iconSize])); CGSize titleSize = [self.titleLabel sizeThatFits:CGSizeMake(maxTitleWidth, CGFLOAT_MAX)]; - // CGFloat contentWidth = ceil([OWSSystemMessageCell iconSize] + - // [OWSSystemMessageCell hSpacing] + - // titleSize.width); - // self.imageView.frame = CGRectMake(round((self.contentView.width - contentWidth) * 0.5f), self.imageView.frame = CGRectMake(round([OWSSystemMessageCell hMargin]), round((self.contentView.height - [OWSSystemMessageCell iconSize]) * 0.5f), [OWSSystemMessageCell iconSize], @@ -239,30 +278,18 @@ round((self.contentView.height - titleSize.height) * 0.5f), ceil(titleSize.width + 1.f), ceil(titleSize.height + 1.f)); - // [self.titleLabel addRedBorder]; - // if (self.subtitleLabel.text.length > 0) { - // CGSize subtitleSize = [self.subtitleLabel - // sizeThatFits:CGSizeMake( - // self.contentView.width - [OWSSystemMessageCell subtitleHMargin] * 2.f, CGFLOAT_MAX)]; - // self.subtitleLabel.frame = CGRectMake(round((self.contentView.width - subtitleSize.width) * 0.5f), - // round(self.bannerView.bottom + OWSSystemMessageCell.subtitleVSpacing), - // ceil(subtitleSize.width), - // ceil(subtitleSize.height)); - // } } + (CGSize)cellSizeForInteraction:(TSInteraction *)interaction collectionViewWidth:(CGFloat)collectionViewWidth { CGSize result = CGSizeMake(collectionViewWidth, 0); - // result.height += self.titleVMargin * 2.f; result.height += self.topVMargin; result.height += self.bottomVMargin; NSString *title = [self titleForInteraction:interaction]; - // NSString *subtitle = [self subtitleForInteraction:interaction]; // Creating a UILabel to measure the layout is expensive, but it's the only - // reliable way to do it. Unread indicators should be rare, so this is acceptable. + // reliable way to do it. UILabel *label = [UILabel new]; label.font = [self titleFont]; label.text = title; @@ -273,19 +300,6 @@ CGFloat contentHeight = ceil(MAX([self iconSize], titleSize.height)); result.height += contentHeight; - // if (subtitle.length > 0) { - // result.height += self.subtitleVSpacing; - // - // label.font = [self subtitleFont]; - // label.text = subtitle; - // // The subtitle may wrap to a second line. - // label.lineBreakMode = NSLineBreakByWordWrapping; - // label.numberOfLines = 0; - // result.height += ceil( - // [label sizeThatFits:CGSizeMake(collectionViewWidth - self.subtitleHMargin * 2.f, - // CGFLOAT_MAX)].height); - // } - return result; } diff --git a/Signal/src/views/TSUnreadIndicatorInteraction.m b/Signal/src/views/TSUnreadIndicatorInteraction.m index a66919210..75a75a3ba 100644 --- a/Signal/src/views/TSUnreadIndicatorInteraction.m +++ b/Signal/src/views/TSUnreadIndicatorInteraction.m @@ -29,6 +29,13 @@ NS_ASSUME_NONNULL_BEGIN missingUnseenSafetyNumberChangeCount:(NSUInteger)missingUnseenSafetyNumberChangeCount { self = [super initWithTimestamp:timestamp inThread:thread]; + // self = [super initWithTimestamp:timestamp + // inThread:thread + // messageBody:nil + // attachmentIds:@[] + // expiresInSeconds:0 + // expireStartedAt:0]; + // - (instancetype)initWithTimestamp:(uint64_t)timestamp inThread:(TSThread *)thread; if (!self) { return self;