From 91f444ba806710406515d73afd690d22bcbc9769 Mon Sep 17 00:00:00 2001 From: Brian Sztamfater Date: Fri, 16 Jul 2021 18:14:05 -0300 Subject: [PATCH] Support mutual contact requests Signed-off-by: Andrea Maria Piana --- resources/images/ui/hand-wave.png | Bin 0 -> 9774 bytes resources/images/ui/hand-wave@2x.png | Bin 0 -> 29859 bytes resources/images/ui/hand-wave@3x.png | Bin 0 -> 61390 bytes src/quo/components/text.cljs | 1 + src/quo/design_system/typography.cljs | 3 + src/status_im/chat/models/input.cljs | 43 +++++ src/status_im/constants.cljs | 15 +- src/status_im/contact/core.cljs | 44 ++++- src/status_im/data_store/contacts.cljs | 19 +- src/status_im/data_store/contacts_test.cljs | 1 + src/status_im/data_store/messages.cljs | 1 + src/status_im/ethereum/json_rpc.cljs | 2 +- src/status_im/multiaccounts/login/core.cljs | 12 ++ src/status_im/notifications_center/core.cljs | 47 +++-- src/status_im/react_native/resources.cljs | 1 + src/status_im/subs.cljs | 40 +++- .../ui/screens/advanced_settings/views.cljs | 20 +- .../ui/screens/chat/audio_message/views.cljs | 9 +- .../chat/components/contact_request.cljs | 86 +++++++++ .../ui/screens/chat/components/input.cljs | 30 +-- .../ui/screens/chat/components/style.cljs | 30 +-- .../ui/screens/chat/message/message.cljs | 43 +++++ .../ui/screens/chat/pinned_messages.cljs | 2 +- .../ui/screens/chat/styles/main.cljs | 10 +- .../screens/chat/styles/message/message.cljs | 29 +++ src/status_im/ui/screens/chat/views.cljs | 83 +++++++-- .../ui/screens/home/views/inner_item.cljs | 1 + .../screens/notifications_center/styles.cljs | 4 +- .../screens/notifications_center/views.cljs | 6 +- .../views/notification.cljs | 176 +++++++++++------- status-go-version.json | 6 +- translations/en.json | 14 +- 32 files changed, 623 insertions(+), 155 deletions(-) create mode 100644 resources/images/ui/hand-wave.png create mode 100644 resources/images/ui/hand-wave@2x.png create mode 100644 resources/images/ui/hand-wave@3x.png create mode 100644 src/status_im/ui/screens/chat/components/contact_request.cljs diff --git a/resources/images/ui/hand-wave.png b/resources/images/ui/hand-wave.png new file mode 100644 index 0000000000000000000000000000000000000000..d761bd07d6114e782bbd208a7519a926da6cedfd GIT binary patch literal 9774 zcmV+}Cehi6P)Ug0-}icbUw3t%`RsqM>0j%d z0vMD*8I(a8ltCGkK^c@m8I(a8ltCGQLMbI*bUU_=QaG&ReA+P&_gaqR*oBaSpTH~Z zhEV8{u0NdPvs)qr=;0ju#TWlHY~8wTr$&NO$Fx(YZ8-DHb3552=xzUjECm749kASi zb7$oj0jjt2z!Aub6-&nL+ST%pWJ;?P1PMYxIayH=ex|Cb>Q|Ruddu^kJK$I$pl^U*Vi6YZfiZsorY}(&> z-KNbu*FOHMrB{2;lbL)OpdjnM*eT&NCupHe>rpkQOenwS!!uXzwuigVr)fcN>sCIz z@Vbw-Y`ZO)G^?oK2gw(JKp=!C6X>uZrB8k1n`c}fROS$yUoOP`b|q%R(C&eo2#S=LUvfyR)x-dYxpbSpWUorDHa4 zt$Vb!wfoyt2!JSuz=xVyT~*R>+G*owoO8}44KP5Z-$6Xm*=RODv`|oX-vy}-{71I$ zM9_fxs@sVeJ%x;1^hxe{9$b3oPujbZD|OxMDh>z!Ry(}p{>v`AWj|l>H@y5y2ex?liGK?0l4BS!+DabWq+1bx?CpmpLM6ahpg0tAO6 z1OgDFxttpD_for`9+i8ZSX;x{E&H~Id%C)Z9cbyfe#3^n^>^KM`y#&HG4~7aUVhK` zV@7``AX(JZlb~t}9BA%1xxIDYN*JKhFCczu!rroKJl*}+sdVe(qx#z3QV(1Wfol9i z1W*zHJ!n0XEvS)fW6Tq+whGDI_H^Ca)nV^`6HXd4r#z}ZChB`)iLSknN+v>k_qE)4 z+if?!x@y&u^!aXI@X!m#P8>5&q#9Vd0;;OOzNU^Jt^D;P7r_9O0pk;C%aU=Rs4GEf znL(9y!O#o?#OkNylIgR_=xj4))Zd;EBSj%--Hd?l2g6W6AR>sqDj>cf0GdDm5iDuc zB60NmyK>KU_xzuZj(4`-*V2}nY5HqG5Q9)!9NaQ`Z1LBwzkW$;db@?Q9@ueY^qfP-~F5ogQP!7wTQ7+~rxxGaSlX>boG7)|qN{e!3Go^QcDf82fF ziWh%8ed?quilD8BYBA{OPEPt{XV*WTefBp)-0jZ!?!~v1L_;4DO94$yL04C@a_5fj z1@Hy#zYw`%UO_w(|JKv^xAFjKdV(08QLu1#W+p=;K@5$@Fkb+wY?)AMe6YG_`%@L} zKB=Vkg3o2&#rktE*^gnQc`=0Q;ZVSGT(CkZZ;9yk_2t-<@#6 zu|EijU2#iKKxcRA)DPEff6(1#+O%onU=xM?BvVO<#ZwpWUb`xAr1xJ4HmBbM zn}~1cbVO@31ZvSvnn1gEg4OjgP(8-YoFwBVDw|IX_PqIfcOOX@^E*Wec4^5NY9HkR z4aHkA5jVp~q95x4(2~Hw1*?6^P`U2GzRrKuO^>}YX2h`bf?^l7Oa&VEw_kYw{qw); zuAejazSo9Sm%f5_8&o9;iIiUY^0xN#VE{?LgJ^0{0~Aw)R1X5DfT8XMJyj2ef?%Q< zBcdOOgflp``8)c$JML!t6wg@HW(mU=sBtu*sC|_4Y=i@e|00N8cr4UL^p)r+L7*)c ztM&I^(APE0y=T>{HI>B=5u*n++k`!P4nDAE&HswH>;1mKLujW_8%-7rK`O5N1O|}w zPju=Ds3zd9!f98Tn$lOj5_*hIiX8rpg zf6rYv{ftxI2>PWq24p-Q15LN4u3eoS`Sz#uk0#QLTZkK>4HSy@A#w-=Y7R4j1Wltw zxOp_WZ!s<7pFT5HU0L>Df*I%67fYlrb=RGD-es|9anZl2W#Dl&&@{EWp>yvr7$DLw zAbOp9DW(sEl*|T!#R?MG1qe>R00x~lkf;HO22UTTwWmhZwm#XjZdpa?j7K)gzOnZh z2^F_9xmg7#&|zlPG~z(Dgl$&QCW~g{H`N_W=k;}6XP*6^j}-YWg`!DSQtBCRzL_zp zq9DFNEe!~+i=*X0v-|(KCgunkedBYcZ^)mCSeCvZW)>-nIxQPW=BrrI4tX#j=C(-z zb?<6Q*Gkc`GanPkkexm~n{` z3CnL0s-y2yq`mbmUv}4xoG|J&pUBK~3J=vqqZN@3NMGxrX#=fW5!SXYnPt@7^o+G- z_FAic-m7%)k_C-h|GOOWECT{WCSs_17KDa1NMZ;i91?*I3nl5O(?oM=;@}cd28w}> zsI8x&zx~2PWb#bSS3dn>OA!?V%_>;n1Uf<{?JzLy&=lK@(`1QE8vj9?)`fbzj^ar4 zHNi@u#;LG>e{&j~tFKMJRrUkOIs&=z>f~E@TwnZ^C2#qCwabhI3vx^wD~mhGblSmE79QvzvqP+d zqs*Q)OM1JO(vp&AMA{7@Su>BFIBtt~-PgZ+&ILcc^s+H`Kl1lmdb=-W>jSfV$xYit zb=~E}*cTQ3LxDt*Ylx!aOCdX=Guw|XiXNDgzVAG=f(*D)l)3$$SwhbT%MDEAHD*d# z)X6$$2pULYf{bb^3aE-KEm0E~yp$VB|FkoUzbwDs_SaX}Q-9})a#0Zo67RJErX&LH zE6W6P&PpKuD5^0|0#gEA9CfL0;_a()ui?=pmz`Z&Qr-BotMA=>IM>|Ku{v6O;KN@L zb;m`-Lai60K*C5e`IzOzS){h1B{+!x<8{}b24+0oCRNX^ggi;Vfk^9C`=D&k>6Vtd zkR+2erWJTc(yE_<6Px#%AGNIzQ`@i7tT^Z<^KX0)V75|1zb1(+(2!B1M4(8AS$a*E zVU9dG<_kt?%fJ3DMucK1i20>p18MKafW+X&SB;vC@ruCGk>WTZ<;Rg@7d5~U3f;Y^ z#E8eA7qsnX5G2geF8~RQMCPdysEKA-LGUndW#kI$ExPR=bK3IH z8nb-&UqEYEE2Oslf*8BLD`}gSfbrhz`o_@lVsz>piw@l+VX7dZCS^R1-~>7>fWeeR zumc@IYA%sz{d2+S^d>1V_EBzDb;qnycR#`Qk2=O9ddhZ2v@2|Z`aG?FtQd|!=-RcC z8jJr~P&Xog22PqFT5G210if~SK)c=rOWBHGcH2=itGaX_z?@ZF4|$ZM4kF#Xs)W*Y z{}k07-vt$Cs1GM(5KRvjVF6l)%khnCjRSkXEU4O9W{T`#=>c~e3=9qmg24k8ihr}2 zj{}3$oZ#y`!PmU%*J9b%AC}0_ca0>{Z;S+RfMl-E4s=ou5sJywNH*(2-6kD}CuIpe4|H&y2`;iHRY87F{gFd!4QMzZ`7O)XLO%rv+D^4iaHAMp)y zPZYF$w-NNyM2Z5-Eh(CRQ)j$I8(yF8SOLF%e{87n{FYGuyP}b^|KHU_me&z0el3(v z#sNhAQd+@i|2LQ&Z({U#0LL1qDf%rz?inij8sD|#sRuP{_~lx+f{d5WRf;F{c-c7g zTqAij%77G68-gPEgq@ek@wQncFyRtCrh(1oP+J?p29nPoBZfd?>CnW;)k1TZ+^}4) zyYZ|~zy3@Np~adWAyx;Tvlck#XCd#(K*R}WaC47I4zfpr5VS!=A5H_+d&Du{oDF%F zynuMPxz1g49t{%S!`Wiw; z{!WWAGwAv`yK=z>%3$Nis5#bWW>MpSb_uMY8KZ>3|Mpy2%1(*CBP?x9G1XOKKZ>=b=q1p<@-48A1%i} zvi;aOQDaPuASwDTLU4bhr8*Vsct_bVe|&G(?@m@r-S=Zg29VGQps6OVfd&F-pmkwp zo-s`XwUFneOcRm7r*hf(~K zk;47VY#@2W%7HXEUB_Z1(3&c!viV=B4L6L+y>@r9ie~49LZBRZSu~+$JJ&!qnJmX& zbN+z!`mlRr6&NHZtWfo@`#Rnim7@-#IQr(r)L*@mn;5W7BXtRH9AE~9iPa2>F&rj# zAOz7o3cGIgB|o{ixc1!dP(^OxfN&rwC&?*sOe-HuR(isPK0g$dlMz1HzKr-L->-Hf zNv^6qJ#kGdXLMM#gjocp76Ky#SVgRH6ezpbCN?dYntT17?=3z-G&^bp{}7;wo!peO z$-vHUnKn7$9-e6=_l3SvMXWmJ1t^g8PZc9ja*hxh7iS5(KwOLBv{_iTnPXLUAP9&b zwK2^2)a`c~UG?7)CM`6+HH3MagIOu9DH;CC?UT79d+~Ktg1(V?z&Y7M0k3`d?7ox8M$%?H?^Wp@($&3MU5h ztq7(s97bZh^@pNVc|hq7Y&8_cVQl!*jNEszeR-h8G?}s>Nd^h8P4<-lQR~Lip7$0K z?W3OyBGYCxqh`W3ot&U|d0NIj5c`J_-g21DCMYc}IV=wLNTpyP9@^DKA@^}HaolYS zX=KWiY@oOna8K{14^HL6a=;MSvlc}Nr0DmVb$=2pp-qrR%rRmLH<4!AM6$^s@*v4z zDgvyvUj|<^0u`k#vlXj)OR`;4EnQFBA>twcwmD>70;Yu#t%-S{Tmn+~1mv_&1fldy z&M>jI5zFzT+@o`no$;5fD;aL!wwnLVS zI7iG4s-uyXJE&iks`E^AC+r(mq417=Sd+` zX%|S!x&Sb{KvNznz&yrT?GB7(J&;^pE(a6rQqELXOc@)ilEb0q4BHL|Eg3I~;qfAt4P?Xav$OzKf{G(AJJrIUJUn^wSe7_daDi{bdGwaDxU+z+zB z&zJ{C8!fvYX;G$;tSPw_%v2p%@r{^P>_c2+ZaFe>s0H@R0!&^qBhE4im2qxYkn{;q zKp7zI8J9FDp(z*1k;$zx^N;q@EY8z5kLatg>P|)0WE{YWE}=$le!^FJ^4nlkJYgnS z&#B=sI_wxOt3!G7FA(&hSdx-TN+C34JojC!)@U1rZ0k?K@zDq*2h(H)=MDrE=|QS< z^Gn=d3hcV2{fEW1&vv*1k4|M#p9}?*0n?rl8hz<|BrxJ^A5vM8K%Lo4oRA$qSz>Ov zKqB9X!4C1uIN7C;*!|{8Dv$a}sVA zpquTulYpC5K8e8jvACI~mX&GPbNjmNt8~g{?EEZgRCuC~+3(k&fKqS}KhLuVWc<7j zt-zEEef}y{a0Et+<7z63DI_Ao0OFR(t$?gG{{6FGLNQ@P`g<0Gt%U za#9GB7lti6uJ@S`t@ei{W#h7#dHicsA%;L{I)CHZ<>YjfYox`?MrmM3X4|xQfMVw* zZr}s%@?L~GL70KX3Rd*y&md3;it2wrfu!F+EU##~hFFc$xuX**&?$~Z(^!sRbl3V5 z>s~a}P`8fu6;;s?S?h!2r!0qSWx1EW9a(Yev1K7GKOLKKI8}Q!W`3YhaDEYMZr233MBmoqLOU8 z5CT}rQ801t{0Pj>4=^CMdI;3*3XYC)Ap42|o7&AvuF?2`sMBK(;XP~G(;KQfdWXs^_}W*GXQOSfT}Uj^-j>#X8b$|24KxljDsANL`mKJ7sVVw=xFpQ zvI@acq{~w8KA?3gx)7XxEmctWOx2F}siS?K=3>4-`Z=Db#+8!OdjLMZ=nr=BY zI3dG%vY>+vgKS|30pev1_CqCv0y4?xx z2+8(u>0rkqPPpmOP*476^P|~dW@{+P@}JZpDcA!zfOMeU=p}+gQzM}Oa#TQEv0_Ed zsufGQKXCKLs;ZfB>O1CK$yWuMVR8+m&V!b|jgE!~P_Ya}@R@kj6XJk$Xe) zs*ivINWovc@Z##4{q{6mGTOPlR~iM zn&o&hfub@30jYkm(!BpvB2V~Q$llf({0hd(q2tXETU~44agcj!&ew0Hx1@a+z1M%_4myB9)$J`~qyldV!yvuhV zY&*#`t(tg}hPyjr-_PAIFnQTyfyl&P>81=SMxiF9Y4gZAPv-j&7>XqwW?GAi4&0gS zN_+_-U%tvp82k+yOq};RI*lt%v`B3eYb#2&8Kgkdey~@`1=_RRPDN-&d(+5ywsUe) zz5{DiW=&I6jneLy%OKB^HxLgTNc^FzN4=$`rG53|kKa@4E-x?hbtd9HpkPv$(uB)< z+c#A9!@0qdDX;6M1d3|${Lgagg1nQB1v_l;uw>7enMkl1l|Dym}YVbP2x zfUAwf6JchAxUULyYnOe&m~nCTzkMY4T>IUe($Q#FYn?5435zHF%(N=W;gDy^8;HSR z;55cmBsE&nw6`t&_K6=~bi)UzL@`Dj_oR$tAAInRLvDhMo}ox3C!HUNjNGKC6g17` zZTh@_g+2A_^slfc3JWXs;W7!L;R9EtV&UnQIdmmYs+~8-LORdOuq$o=iOjT`QnJ@}$S)#!1JN)vMaM{tJ)Nr?)(^bv zLVn>{))kgeK~A){&hKsi;t5x_MTVVnUNBVAkU}68&ElPJ86XKawG2oTOGx3$Ae5Ih zUedxHxQ|1Hi-h^oMca2IpvybE>5!($BY~DFv1*X0Jn82zgT|XjVJVW zjNs@w4Ur+oeBU3c>{2yq2RjasJQt)kkOoWgk)4TD7DG+>!L#=4Xs<-3AkDN0&MQ%D zpoqs0X6J&Lh>~VL-TMKWoeLhKvd;eQkx2Ho_C#R>yu42#-pD7DaI&2I~K0Yk?d_{I!1aSdyB&RBouHNS)_nDVAz#-uG zCL}lVp_xAj@$jlnVL2TVQzHa8X=hKt#gS*TO|LHqDm`)jAIqvwxguCpp|E^WV<76lHPUik17={tuP5q&Cb7tCG~-ys?Mi(* zS4*e)>En_^dgndVjE8ZdG9frG|{r3>O!kOaLp+jn`k(^AQTE% ztZR+=#)jR^^H)B$Y?8apEq5$^Wmr||cfe9p8s5#G=F~Z_zWmOH6-(!y-PXe>X4bgObBqO|a4asu^Qr9~;Lu31&Y^_M=Yvj-%#&i9iJ#znaa!+?d zlDo4<6RG#`c0t=l)#RVWMZSZOXUQvLGyA4H)>f1iKPUT~aN43JA8)IFX3d(Xs@-jt zJoLm1jF)DZi8pvi`Y_iGqgXEB(tYgs3{(OSa41+@ncnI=L?#R;& z)}tec@qE87^9zHR+u1#ONbz-OR@+2oR#{q+RF8Y>t@l?w{P3a@cbkQGEq`Is_)*7| zMC2W*R5!#@3LNaz&fdJM?b$o$UH-wXSAV22&tj`EQ#t;&34d}b!=aDk)gbR@fR&hd`yysX=fFAsFM)FT}z zkGAEyn4eyG$AJ+;%daR72MpFo%ksmPmacP}8avjkd3yO!cb|C+9;lyr;W3kk4=KAY z=%Y;x%w#GBdz*Wv`J!cC&pl7@q(>UWnhVd2mLBs4dj*Q=YM&GA@T8i935TX_X_f{& z<}fQN$=*DzWtk0V8o&&YX+3o{lR$PL#R4y$W)M!;vou41==#3K?nouCYVCcq{)$KL zzNv2e?q!J-t2T)IL6vAY*i>6neeS$F7H#zISO4OR{%78Pc}60cJT(~f@4EAsEB@H$ zIa=35l*X4VZF>WA19cm4nMXn-cX_ZGy-PdiV%`0Tq0d=9X zK_uQ|J0_EOEGLTz*b8?hsR#t$5S)P+%dltWq_S=pHnE(LnI_~>@(NTL z@Bk+Nz_dib5fAueC@l#;apqT#yW?Bmy0rE49@F(F>ZY3?NOf+!i9P8npvFt=Sq{M+ zTNjAzU?V$aOhe)UnL1kQqz_J`RfeHEG_D0tTa_65azuLc^aW zL+4%qd6t5L$mF*x?!EG(%{vywlS&N>LPU|}k|J`gex31_u#8Lzi(_lFOP&9Hq8Gh?DD1hX>vfo?yeDlpqww>|S2~&m-E4wio z2{g0UXBkEub2|lMiGXmAhV^xOlBp{*|)=MML)y_B9Gluw%cR zAyfDBwj;U$q(wcHHV0F1tZLdoWh z)$#qUZ(Xl0zUS8uf8}eFPaHYC>h_AVaI++6NLHuV3oo{n4=H`u-m>q2jplq$p}Rad z;l?)t<GDn_tZig3^FF>CGW|WqQ5L z+cF?jyN1+U^a>P6j*2<$>-(VAta+lky{XxE={58BK^~-M`|}k+<>lwpo-JqShT>Ys zw0R|7^VrLsXDN{z<3Mge1Q{FbT}bSQWZ5jUqf-$iUoDX6ga#-*VFoGveghOpjtYo} zD@Xd}UtZb0du?EN?AfJSy#6{(jq$DkCSHrjmIw|y-Y;m(mFz|C4%8bHIloBy93m0; zt5hTzt187ajJUoX(iq;nQ5i_H5yD@ zeDYx#k|e(8d{Gqo8SKUQu+#iM`}Pg^XEnZ4*}-s6DsiJ7#4d~S01 zaK8SXZDW0W{pG3nzC~)PZK%PX?|0Va(yZyfy>8I+$}gALVP-hslc1<%T$fmO+AU<{ zmA{3fECVb${d^|)@Q<54sk$~jS?V|6y530ayH-`&%UJ`Lt8ke|12RM7J__J4JH*Wp zSw;~G1d!jJ_>ok3@=U0`qW;q-QFfl2FKx{Wh)2^z+8X!yHMKWs-L@tYj;;B=VI;0s zlLx05x|a5rX#&90^hTYSi1|+m3DQucvNc#b^*6%AGwvzmyW2iX29zfDr)XOjPgN3o zeyGP9r<$fY#WYd@;LrEl{rF59MXaYuz5oU=;ksZ^^*?+gzP+4Oo)`P9WA|lY2EU@c zfRbqV;}Em?%~3eIz=TUv7)<9Z8b|xBvhE07*qo IM6N<$f~645nE(I) literal 0 HcmV?d00001 diff --git a/resources/images/ui/hand-wave@2x.png b/resources/images/ui/hand-wave@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..80fd494cd9b11ba24113bc9f91c6f51f831899da GIT binary patch literal 29859 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 <9G1 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 Q7vk#xB^4!V#0&%f2X2MSumAu6 literal 0 HcmV?d00001 diff --git a/src/quo/components/text.cljs b/src/quo/components/text.cljs index fa26429271..1434a0b7eb 100644 --- a/src/quo/components/text.cljs +++ b/src/quo/components/text.cljs @@ -28,6 +28,7 @@ :inherit nil) (case (or size :base) :tiny typography/tiny + :x-small typography/x-small :small typography/small :base typography/base :large typography/large diff --git a/src/quo/design_system/typography.cljs b/src/quo/design_system/typography.cljs index e37f71eaff..dddf0bd86f 100644 --- a/src/quo/design_system/typography.cljs +++ b/src/quo/design_system/typography.cljs @@ -3,6 +3,9 @@ (def tiny {:font-size 10 :line-height 14}) +(def x-small {:font-size 12 + :line-height 16}) + (def small {:font-size 13 :line-height 18}) diff --git a/src/status_im/chat/models/input.cljs b/src/status_im/chat/models/input.cljs index 023dc47445..4587bffd49 100644 --- a/src/status_im/chat/models/input.cljs +++ b/src/status_im/chat/models/input.cljs @@ -143,6 +143,20 @@ :on-error #(log/error "failed to delete message message " %) :on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])}]}) +(fx/defn show-contact-request-input + "Sets reference to previous chat message and focuses on input" + {:events [:chat.ui/send-contact-request]} + [{:keys [db] :as cofx}] + (let [current-chat-id (:current-chat-id db)] + {:db (-> db + (assoc-in [:chat/inputs current-chat-id :metadata :sending-contact-request] + current-chat-id) + (assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message] + nil) + (assoc-in [:chat/inputs current-chat-id :metadata :editing-message] nil) + (update-in [:chat/inputs current-chat-id :metadata] + dissoc :sending-image))})) + (fx/defn cancel-message-reply "Cancels stage message reply" {:events [:chat.ui/cancel-message-reply]} @@ -179,6 +193,7 @@ (fx/defn clean-input [{:keys [db] :as cofx} current-chat-id] (fx/merge cofx {:db (-> db + (assoc-in [:chat/inputs current-chat-id :metadata :sending-contact-request] nil) (assoc-in [:chat/inputs current-chat-id :metadata :sending-image] nil) (assoc-in [:chat/inputs current-chat-id :metadata :editing-message] nil) (assoc-in [:chat/inputs current-chat-id :metadata :responding-to-message] nil))} @@ -262,6 +277,34 @@ (mentions/clear-mentions) (mentions/clear-cursor)))) +(fx/defn send-contact-request + {:events [:contacts/send-contact-request]} + [{:keys [db] :as cofx} public-key message] + (fx/merge cofx + {::json-rpc/call [{:method "wakuext_sendContactRequest" + :js-response true + :params [{:id public-key :message message}] + :on-error #(log/warn "failed to send a contact request" %) + + :on-success #(re-frame/dispatch [:transport/message-sent %])}]} + + (mentions/clear-mentions) + (mentions/clear-cursor) + (clean-input (:current-chat-id db)) + (process-cooldown))) + +(fx/defn cancel-contact-request + "Cancels contact request" + {:events [:chat.ui/cancel-contact-request]} + [{:keys [db] :as cofx}] + (let [current-chat-id (:current-chat-id db)] + (fx/merge cofx + {:db (assoc-in db [:chat/inputs current-chat-id :metadata :sending-contact-request] nil)} + (mentions/clear-mentions) + (mentions/clear-cursor) + (clean-input (:current-chat-id db)) + (process-cooldown)))) + (fx/defn chat-send-sticker {:events [:chat/send-sticker]} [{{:keys [current-chat-id] :as db} :db :as cofx} {:keys [hash packID] :as sticker}] diff --git a/src/status_im/constants.cljs b/src/status_im/constants.cljs index 2b719e6606..59e98ac5ff 100644 --- a/src/status_im/constants.cljs +++ b/src/status_im/constants.cljs @@ -13,6 +13,13 @@ (def ^:const content-type-audio 8) (def ^:const content-type-community 9) (def ^:const content-type-gap 10) +(def ^:const content-type-contact-request 11) ;; TODO: temp, will be removed + +(def ^:const contact-request-state-none 0) +(def ^:const contact-request-state-mutual 1) +(def ^:const contact-request-state-sent 2) +(def ^:const contact-request-state-received 3) +(def ^:const contact-request-state-dismissed 4) (def ^:const emoji-reaction-love 1) (def ^:const emoji-reaction-thumbs-up 2) @@ -28,6 +35,10 @@ (def ^:const timeline-chat-type 5) (def ^:const community-chat-type 6) +(def ^:const contact-request-message-state-pending 1) +(def ^:const contact-request-message-state-accepted 2) +(def ^:const contact-request-message-state-declined 3) + (def request-to-join-pending-state 1) (def reactions {emoji-reaction-love (:love resources/reactions) @@ -161,6 +172,8 @@ (def ^:const activity-center-notification-type-private-group-chat 2) (def ^:const activity-center-notification-type-mention 3) (def ^:const activity-center-notification-type-reply 4) +(def ^:const activity-center-notification-type-contact-request 5) +(def ^:const activity-center-notification-type-contact-request-retracted 6) (def ^:const visibility-status-unknown 0) (def ^:const visibility-status-automatic 1) @@ -173,4 +186,4 @@ (def ^:const sticker-pack-status-installed 1) (def ^:const sticker-pack-status-pending 2) -(def ^:const sticker-pack-status-owned 3) \ No newline at end of file +(def ^:const sticker-pack-status-owned 3) diff --git a/src/status_im/contact/core.cljs b/src/status_im/contact/core.cljs index 24b6f48047..2dfe01d071 100644 --- a/src/status_im/contact/core.cljs +++ b/src/status_im/contact/core.cljs @@ -5,6 +5,7 @@ [status-im.ethereum.json-rpc :as json-rpc] [status-im.navigation :as navigation] [status-im.utils.fx :as fx] + [status-im.async-storage.core :as async-storage] [taoensso.timbre :as log] [status-im.constants :as constants] [status-im.contact.block :as contact.block])) @@ -28,13 +29,6 @@ (= public-key (:public-key multiaccount)) (assoc :name (:name multiaccount)))) -(defn- own-info - [db] - (let [{:keys [name preferred-name identicon address]} (:multiaccount db)] - {:name (or preferred-name name) - :profile-image identicon - :address address})) - (fx/defn ensure-contacts [{:keys [db]} contacts chats] (let [events @@ -66,6 +60,13 @@ (when (> (count events) 1) {:dispatch-n events})))) +(defn- own-info + [db] + (let [{:keys [name preferred-name identicon address]} (:multiaccount db)] + {:name (or preferred-name name) + :profile-image identicon + :address address})) + (fx/defn send-contact-request {:events [::send-contact-request]} [{:keys [db] :as cofx} public-key] @@ -92,12 +93,33 @@ "Remove a contact from current account's contact list" {:events [:contact.ui/remove-contact-pressed]} [{:keys [db]} {:keys [public-key]}] - {:db (assoc-in db [:contacts/contacts public-key :added] false) + {:db (-> db + (assoc-in [:contacts/contacts public-key :added] false) + (assoc-in [:contacts/contacts public-key :contact-request-state] constants/contact-request-state-none)) ::json-rpc/call [{:method "wakuext_removeContact" :params [public-key] + :on-success #(log/debug "contact removed successfully")} + {:method "wakuext_retractContactRequest" + :params [{:contactId public-key}] :on-success #(log/debug "contact removed successfully")}] :dispatch [:offload-messages constants/timeline-chat-id]}) +(fx/defn accept-contact-request + {:events [:contact-requests.ui/accept-request]} + [{:keys [db]} id] + {::json-rpc/call [{:method "wakuext_acceptContactRequest" + :params [{:id id}] + :js-response true + :on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])}]}) + +(fx/defn decline-contact-request + {:events [:contact-requests.ui/decline-request]} + [{:keys [db]} id] + {::json-rpc/call [{:method "wakuext_dismissContactRequest" + :params [{:id id}] + :js-response true + :on-success #(re-frame/dispatch [:sanitize-messages-and-process-response %])}]}) + (fx/defn initialize-contacts [cofx] (contacts-store/fetch-contacts-rpc cofx #(re-frame/dispatch [::contacts-loaded %]))) @@ -119,3 +141,9 @@ nickname #(re-frame/dispatch [:sanitize-messages-and-process-response %])) (navigation/navigate-back))) + +(fx/defn switch-mutual-contact-requests-enabled + {:events [:multiaccounts.ui/switch-mutual-contact-requests-enabled]} + [{:keys [db]} enabled?] + {::async-storage/set! {:mutual-contact-requests-enabled? enabled?} + :db (assoc db :mutual-contact-requests/enabled? enabled?)}) diff --git a/src/status_im/data_store/contacts.cljs b/src/status_im/data_store/contacts.cljs index 09a0fdf707..8f06d9d310 100644 --- a/src/status_im/data_store/contacts.cljs +++ b/src/status_im/data_store/contacts.cljs @@ -5,13 +5,18 @@ [taoensso.timbre :as log])) (defn <-rpc [contact] - (clojure.set/rename-keys contact {:id :public-key - :ensVerifiedAt :ens-verified-at - :ensVerified :ens-verified - :ensVerificationRetries :ens-verification-retries - :lastENSClockValue :last-ens-clock-value - :lastUpdated :last-updated - :localNickname :nickname})) + (-> contact + (clojure.set/rename-keys {:id :public-key + :ensVerifiedAt :ens-verified-at + :ensVerified :ens-verified + :ensVerificationRetries :ens-verification-retries + :hasAddedUs :has-added-us + :contactRequestState :contact-request-state + :lastENSClockValue :last-ens-clock-value + :lastUpdated :last-updated + :localNickname :nickname}) + (assoc :mutual? (and (:added contact) + (:hasAddedUs contact))))) (fx/defn fetch-contacts-rpc [_ on-success] diff --git a/src/status_im/data_store/contacts_test.cljs b/src/status_im/data_store/contacts_test.cljs index 294d1317b6..03cb559829 100644 --- a/src/status_im/data_store/contacts_test.cljs +++ b/src/status_im/data_store/contacts_test.cljs @@ -10,6 +10,7 @@ :lastUpdated 1} expected-contact {:public-key "pk" :address "address" + :mutual? nil :name "name" :identicon "identicon" :last-updated 1}] diff --git a/src/status_im/data_store/messages.cljs b/src/status_im/data_store/messages.cljs index 65ba03006b..0b37e434b2 100644 --- a/src/status_im/data_store/messages.cljs +++ b/src/status_im/data_store/messages.cljs @@ -20,6 +20,7 @@ (clojure.set/rename-keys {:id :message-id :whisperTimestamp :whisper-timestamp :editedAt :edited-at + :contactRequestState :contact-request-state :commandParameters :command-parameters :gapParameters :gap-parameters :messageType :message-type diff --git a/src/status_im/ethereum/json_rpc.cljs b/src/status_im/ethereum/json_rpc.cljs index 84c65131bb..2891d1e65a 100644 --- a/src/status_im/ethereum/json_rpc.cljs +++ b/src/status_im/ethereum/json_rpc.cljs @@ -61,4 +61,4 @@ ::call (fn [params] (doseq [param params] - (call param)))) \ No newline at end of file + (call param)))) diff --git a/src/status_im/multiaccounts/login/core.cljs b/src/status_im/multiaccounts/login/core.cljs index d27d1ffdd3..0a8c587ce1 100644 --- a/src/status_im/multiaccounts/login/core.cljs +++ b/src/status_im/multiaccounts/login/core.cljs @@ -94,6 +94,13 @@ :wallet-connect-enabled? #(re-frame/dispatch [:multiaccounts.ui/switch-wallet-connect-enabled %])))) +(re-frame/reg-fx + ::initialize-mutual-contact-requests + (fn [] + (async-storage/get-item + :mutual-contact-requests-enabled? + #(re-frame/dispatch [:multiaccounts.ui/switch-mutual-contact-requests-enabled %])))) + (defn rpc->accounts [accounts] (reduce (fn [acc {:keys [chat type wallet] :as account}] (if chat @@ -359,6 +366,10 @@ [cofx] {::initialize-wallet-connect nil}) +(fx/defn initialize-mutual-contact-requests + [cofx] + {::initialize-mutual-contact-requests nil}) + (fx/defn get-node-config-callback {:events [::get-node-config-callback]} [{:keys [db] :as cofx} node-config-json] @@ -393,6 +404,7 @@ (initialize-appearance) (initialize-communities-enabled) (initialize-wallet-connect) + (initialize-mutual-contact-requests) (get-node-config) (communities/fetch) (logging/set-log-level (:log-level multiaccount)) diff --git a/src/status_im/notifications_center/core.cljs b/src/status_im/notifications_center/core.cljs index 41c53677d6..81ab197167 100644 --- a/src/status_im/notifications_center/core.cljs +++ b/src/status_im/notifications_center/core.cljs @@ -1,23 +1,38 @@ (ns status-im.notifications-center.core (:require [status-im.utils.fx :as fx] [status-im.ethereum.json-rpc :as json-rpc] + [status-im.constants :as constants] [taoensso.timbre :as log] [re-frame.core :as re-frame] [status-im.data-store.activities :as data-store.activities])) +(def non-dismissable-notifications + #{constants/activity-center-notification-type-contact-request + constants/activity-center-notification-type-contact-request-retracted}) + (fx/defn handle-activities [{:keys [db]} activities] (let [{:keys [unread-count notifications]} (reduce (fn [acc {:keys [read dismissed accepted] :as notification}] - (as-> acc a - (if read - (update a :unread-count dec) - (update a :unread-count inc)) + (let [index-existing (->> (map-indexed vector (:notifications acc)) + (filter (fn [[idx {:keys [id]}]] (= id (:id notification)))) + first + first)] + (as-> acc a + (if read + (update a :unread-count dec) + (update a :unread-count inc)) - (if (or dismissed accepted) - (update a :notifications (fn [items] (remove #(= (:id notification) (:id %)) items))) - (update a :notifications conj notification)))) + (if index-existing + (if (or dismissed accepted) + ;; Remove at specific location + (assoc a :notifications + (into (subvec (:notifications a) 0 index-existing) (subvec (:notifications a) (inc index-existing)))) + ;; Replace element + (do + (assoc-in a [:notifications index-existing] notification))) + (update a :notifications conj notification))))) {:unread-count (get db :activity.center/notifications-count 0) - :notifications (get-in db [:activity.center/notifications :notifications])} + :notifications (into [] (get-in db [:activity.center/notifications :notifications]))} activities)] (merge {:db (-> db @@ -69,14 +84,21 @@ {:events [:accept-all-activity-center-notifications-from-chat]} [{:keys [db]} chat-id] (let [notifications (get-in db [:activity.center/notifications :notifications]) - notifications-from-chat (filter #(= chat-id (:chat-id %)) notifications) + notifications-from-chat (filter #(and + (= chat-id (:chat-id %)) + (not (contains? non-dismissable-notifications (:type %)))) + notifications) notifications-from-chat-not-read (filter #(and (= chat-id (:chat-id %)) - (not (:read %))) notifications) - ids (map :id notifications-from-chat)] + (not (:read %))) + notifications) + ids (into #{} (map :id notifications-from-chat))] (when (seq ids) {:db (-> db (update-in [:activity.center/notifications :notifications] - (fn [items] (filter #(not (= chat-id (:chat-id %))) items))) + (fn [items] + (filter + #(not (contains? ids (:id %))) + items))) (update :activity.center/notifications-count - (min (db :activity.center/notifications-count) (count notifications-from-chat-not-read)))) ::json-rpc/call [{:method "wakuext_acceptActivityCenterNotifications" :params [ids] @@ -170,4 +192,3 @@ (update-in [:activity.center/notifications :notifications] concat (map data-store.activities/<-rpc notifications)))}) - diff --git a/src/status_im/react_native/resources.cljs b/src/status_im/react_native/resources.cljs index 2ff16e14b1..375c8c0ca7 100644 --- a/src/status_im/react_native/resources.cljs +++ b/src/status_im/react_native/resources.cljs @@ -45,6 +45,7 @@ :notifications (js/require "../resources/images/ui/notifications.png") :collectible (js/require "../resources/images/ui/collectible.png") :collectible-dark (js/require "../resources/images/ui/collectible-dark.png") + :hand-wave (js/require "../resources/images/ui/hand-wave.png") :graph (js/require "../resources/images/ui/graph.png")}) (defn get-theme-image [k] diff --git a/src/status_im/subs.cljs b/src/status_im/subs.cljs index f4c5843b0e..d9c3217ae2 100644 --- a/src/status_im/subs.cljs +++ b/src/status_im/subs.cljs @@ -264,6 +264,9 @@ (reg-root-key-sub :wallet-connect/sessions :wallet-connect/sessions) (reg-root-key-sub :wallet-connect-legacy/sessions :wallet-connect-legacy/sessions) (reg-root-key-sub :wallet-connect/session-managed :wallet-connect/session-managed) +(reg-root-key-sub :contact-requests/pending :contact-requests/pending) + +(reg-root-key-sub :mutual-contact-requests/enabled? :mutual-contact-requests/enabled?) (re-frame/reg-sub :communities @@ -941,6 +944,13 @@ (fn [ui-props [_ prop]] (get ui-props prop))) +(re-frame/reg-sub + :chats/current-chat-contact + :<- [:contacts/contacts] + :<- [:chats/current-chat-id] + (fn [[contacts current-chat-id]] + (get contacts current-chat-id))) + (re-frame/reg-sub :chats/home-list-chats :<- [::chats] @@ -1033,7 +1043,10 @@ :<- [:multiaccount/public-key] :<- [:communities/current-community] :<- [:contacts/blocked-set] - (fn [[{:keys [group-chat chat-id] :as current-chat} my-public-key community blocked-users-set]] + :<- [:contacts/contacts] + :<- [:chat/inputs] + :<- [:mutual-contact-requests/enabled?] + (fn [[{:keys [group-chat chat-id] :as current-chat} my-public-key community blocked-users-set contacts inputs mutual-contact-requests-enabled?]] (when current-chat (cond-> current-chat (chat.models/public-chat? current-chat) @@ -1049,7 +1062,15 @@ (assoc :show-input? true) (not group-chat) - (assoc :show-input? (not (contains? blocked-users-set chat-id))))))) + (assoc :show-input? + (and + (or + (not mutual-contact-requests-enabled?) + (get-in inputs [chat-id :metadata :sending-contact-request]) + (and mutual-contact-requests-enabled? + (= constants/contact-request-state-mutual + (get-in contacts [chat-id :contact-request-state])))) + (not (contains? blocked-users-set chat-id)))))))) (re-frame/reg-sub :chats/current-chat-chat-view @@ -1300,6 +1321,12 @@ (fn [{:keys [metadata]}] (:editing-message metadata))) +(re-frame/reg-sub + :chats/sending-contact-request + :<- [:chats/current-chat-inputs] + (fn [{:keys [metadata]}] + (:sending-contact-request metadata))) + (re-frame/reg-sub :chats/sending-image :<- [:chats/current-chat-inputs] @@ -1321,22 +1348,27 @@ :<- [:current-chat/metadata] :<- [:chats/reply-message] :<- [:chats/edit-message] - (fn [[{:keys [processing]} sending-image mainnet? one-to-one-chat? {:keys [public?]} reply edit]] + :<- [:chats/sending-contact-request] + (fn [[{:keys [processing]} sending-image mainnet? one-to-one-chat? {:keys [public?]} reply edit sending-contact-request]] (let [sending-image (seq sending-image)] {:send (not processing) :stickers (and (or config/stickers-test-enabled? mainnet?) (not sending-image) + (not sending-contact-request) (not reply)) :image (and (not reply) (not edit) + (not sending-contact-request) (not public?)) :extensions (and one-to-one-chat? (or config/commands-enabled? mainnet?) (not edit) + (not sending-contact-request) (not reply)) :audio (and (not sending-image) (not reply) (not edit) + (not sending-contact-request) (not public?)) :sending-image sending-image}))) @@ -1896,6 +1928,8 @@ (filter (fn [{:keys [type last-message]}] (or (and (= constants/activity-center-notification-type-one-to-one-chat type) (not (nil? last-message))) + (= constants/activity-center-notification-type-contact-request type) + (= constants/activity-center-notification-type-contact-request-retracted type) (= constants/activity-center-notification-type-private-group-chat type) (= constants/activity-center-notification-type-reply type) (= constants/activity-center-notification-type-mention type))) diff --git a/src/status_im/ui/screens/advanced_settings/views.cljs b/src/status_im/ui/screens/advanced_settings/views.cljs index de937173da..aee913f6e2 100644 --- a/src/status_im/ui/screens/advanced_settings/views.cljs +++ b/src/status_im/ui/screens/advanced_settings/views.cljs @@ -14,8 +14,9 @@ wakuv2-flag current-fleet webview-debug - wallet-connect-enabled? - new-ui-enabled?]}] + new-ui-enabled? + mutual-contact-requests-enabled? + wallet-connect-enabled?]}] (keep identity [{:size :small @@ -108,6 +109,15 @@ [:multiaccounts.ui/waku-bloom-filter-mode-switched (not waku-bloom-filter-mode)]) :accessory :switch :active waku-bloom-filter-mode} + {:size :small + :title (i18n/label :t/mutual-contact-requests) + :accessibility-label :wallet-connect-settings-switch + :container-margin-bottom 8 + :on-press + #(re-frame/dispatch + [:multiaccounts.ui/switch-mutual-contact-requests-enabled (not mutual-contact-requests-enabled?)]) + :accessory :switch + :active mutual-contact-requests-enabled?} {:size :small :title (i18n/label :t/wallet-connect) :accessibility-label :wallet-connect-settings-switch @@ -143,6 +153,7 @@ transactions-management-enabled? [:wallet/transactions-management-enabled?] current-log-level [:log-level/current-log-level] current-fleet [:fleets/current-fleet] + mutual-contact-requests-enabled? [:mutual-contact-requests/enabled?] wallet-connect-enabled? [:wallet-connect/enabled?]] [list/flat-list {:data (flat-list-data @@ -155,7 +166,8 @@ :wakuv2-flag wakuv2-flag :waku-bloom-filter-mode waku-bloom-filter-mode :webview-debug webview-debug - :wallet-connect-enabled? wallet-connect-enabled? - :new-ui-enabled? @config/new-ui-enabled?}) + :new-ui-enabled? @config/new-ui-enabled? + :mutual-contact-requests-enabled? mutual-contact-requests-enabled? + :wallet-connect-enabled? wallet-connect-enabled?}) :key-fn (fn [_ i] (str i)) :render-fn render-item}])) diff --git a/src/status_im/ui/screens/chat/audio_message/views.cljs b/src/status_im/ui/screens/chat/audio_message/views.cljs index ed389fbd3d..a97b3016b0 100644 --- a/src/status_im/ui/screens/chat/audio_message/views.cljs +++ b/src/status_im/ui/screens/chat/audio_message/views.cljs @@ -227,13 +227,13 @@ [react/animated-view {:style (styles/rec-outer-circle outer-scale)}] [react/animated-view {:style (styles/rec-inner-circle inner-scale inner-border-radius)}]]])) -(defn- cancel-button [disabled? on-press] +(defn- cancel-button [disabled? on-press contact-request] [pressable/pressable {:type :scale :disabled disabled? :on-press on-press} [react/view {:style (input.style/send-message-button)} [icons/icon :main-icons/close - {:container-style (merge (input.style/send-message-container) {:background-color colors/gray}) + {:container-style (merge (input.style/send-message-container contact-request) {:background-color colors/gray}) :accessibility-label :cancel-message-button :color colors/white-persist}]]]) @@ -272,13 +272,14 @@ (reset! on-background-cb nil))} (let [base-params {:rec-button-anim-value rec-button-anim-value :ctrl-buttons-anim-value ctrl-buttons-anim-value - :timer timer}] + :timer timer} + contact-request @(re-frame/subscribe [:chats/sending-contact-request])] [react/view {:style styles/container} [react/text {:style styles/timer :accessibility-label :audio-message-recorded-time} @timer] [react/view {:style styles/buttons-container} [react/animated-view {:style {:opacity ctrl-buttons-anim-value}} - [cancel-button (:cancel-disabled? @state) #(stop-recording base-params)]] + [cancel-button (:cancel-disabled? @state) #(stop-recording base-params) contact-request]] [rec-button-view (merge base-params {:state state})] [react/animated-view {:style {:opacity ctrl-buttons-anim-value}} [input/send-button (fn [] (cond diff --git a/src/status_im/ui/screens/chat/components/contact_request.cljs b/src/status_im/ui/screens/chat/components/contact_request.cljs new file mode 100644 index 0000000000..f6f0813863 --- /dev/null +++ b/src/status_im/ui/screens/chat/components/contact_request.cljs @@ -0,0 +1,86 @@ +(ns status-im.ui.screens.chat.components.contact-request + (:require [quo.core :as quo] + [quo.react :as quo.react] + [quo.react-native :as rn] + [quo.design-system.colors :as quo.colors] + [status-im.i18n.i18n :as i18n] + [status-im.ethereum.stateofus :as stateofus] + [status-im.ui.screens.chat.components.style :as styles] + [re-frame.core :as re-frame] + [clojure.string :as string]) + (:require-macros [status-im.utils.views :refer [defview letsubs]])) + +(def ^:private contact-request-symbol "↪ ") + +(defn input-focus [text-input-ref] + (some-> ^js (quo.react/current-ref text-input-ref) .focus)) + +(defn format-author [contact-name] + (let [author (if (or (= (aget contact-name 0) "@") + ;; in case of replies + (= (aget contact-name 1) "@")) + (or (stateofus/username contact-name) + (subs contact-name 0 81)) + contact-name)] + (i18n/label :contact-requesting-to {:author author}))) + +(defn format-contact-request-author [from username current-public-key] + (or (and (= from current-public-key) + (str contact-request-symbol (i18n/label :t/You))) + (str contact-request-symbol (format-author username)))) + +(defn get-quoted-text-with-mentions [parsed-text] + (string/join + (mapv (fn [{:keys [type literal children]}] + (cond + (= type "paragraph") + (get-quoted-text-with-mentions children) + + (= type "mention") + @(re-frame/subscribe [:contacts/contact-name-by-identity literal]) + + (seq children) + (get-quoted-text-with-mentions children) + + :else + literal)) + parsed-text))) + +(defn contact-request-message [their-public-key] + (let [{:keys [input-text]} @(re-frame/subscribe [:chats/current-chat-inputs])] + [rn/view {:style {:flex-direction :row}} + [rn/view {:style (styles/contact-request-content)} + [quo/button {:type :secondary + :weight :medium + :number-of-lines 1 + :style {:line-height 18} + :on-press #(re-frame/dispatch [:chat.ui/cancel-contact-request])} + (i18n/label :t/cancel)] + [quo/button {:type :secondary + :disabled (string/blank? input-text) + :weight :medium + :after :main-icons/send + :on-press #(re-frame/dispatch [:contacts/send-contact-request their-public-key input-text]) + :style {:line-height 18}} + (i18n/label :t/send-request)]]])) + +(defn focus-input-on-contact-request [contact-request had-contact-request text-input-ref] + ;;when we show contact-request we focus input + (when-not (= contact-request @had-contact-request) + (reset! had-contact-request contact-request) + (when contact-request + (js/setTimeout #(input-focus text-input-ref) 250)))) + +(defn contact-request-message-wrapper [contact-request] + [rn/view {:style {:padding-horizontal 15 + :border-top-width 1 + :border-top-color (:ui-01 @quo.colors/theme) + :padding-vertical 8}} + [contact-request-message contact-request]]) + +(defview contact-request-message-auto-focus-wrapper [text-input-ref] + (letsubs [had-reply (atom nil) + contact-request @(re-frame/subscribe [:chats/sending-contact-request])] + {:component-did-mount #(focus-input-on-contact-request contact-request had-reply text-input-ref)} + (when contact-request + [contact-request-message-wrapper contact-request]))) diff --git a/src/status_im/ui/screens/chat/components/input.cljs b/src/status_im/ui/screens/chat/components/input.cljs index 7644a58021..853e7fd7b5 100644 --- a/src/status_im/ui/screens/chat/components/input.cljs +++ b/src/status_im/ui/screens/chat/components/input.cljs @@ -73,13 +73,14 @@ [icons/icon :main-icons/keyboard (styles/icon false)] [icons/icon :main-icons/speech (styles/icon false)])]]) -(defn send-button [on-send] +(defn send-button [on-send contact-request] [rn/touchable-opacity {:on-press-in on-send} [rn/view {:style (styles/send-message-button)} - [icons/icon :main-icons/arrow-up - {:container-style (styles/send-message-container) - :accessibility-label :send-message-button - :color (styles/send-icon-color)}]]]) + (when-not contact-request + [icons/icon :main-icons/arrow-up + {:container-style (styles/send-message-container contact-request) + :accessibility-label :send-message-button + :color (styles/send-icon-color)}])]]) (defn on-selection-change [timeout-id last-text-change mentionable-users args] (let [selection (.-selection ^js (.-nativeEvent ^js args)) @@ -232,10 +233,11 @@ mentionable-users @(re-frame/subscribe [:chats/mentionable-users]) timeout-id (atom nil) last-text-change (atom nil) - mentions-enabled (get @mentions-enabled chat-id)] + mentions-enabled (get @mentions-enabled chat-id) + contact-request @(re-frame/subscribe [:chats/sending-contact-request])] [rn/text-input - {:style (styles/text-input) + {:style (styles/text-input contact-request) :ref (:text-input-ref refs) :max-font-size-multiplier 1 :accessibility-label :chat-message-input @@ -327,8 +329,8 @@ (when (seq sending-image) [reply/send-image sending-image]))) -(defn actions [extensions image show-send actions-ref active-panel set-active-panel] - [rn/view {:style (styles/actions-wrapper show-send) +(defn actions [extensions image show-send actions-ref active-panel set-active-panel contact-request] + [rn/view {:style (styles/actions-wrapper (and (not contact-request) show-send)) :ref actions-ref} (when extensions [touchable-icon {:panel :extensions @@ -354,12 +356,13 @@ :sticker-ref sticker-ref :text-input-ref text-input-ref} {:keys [send stickers image extensions audio sending-image]} @toolbar-options - show-send (or sending-image (seq (get @input-texts chat-id)))] + show-send (or sending-image (seq (get @input-texts chat-id))) + contact-request @(re-frame/subscribe [:chats/sending-contact-request])] [rn/view {:style (styles/toolbar) :on-layout on-chat-toolbar-layout} ;;EXTENSIONS and IMAGE buttons - [actions extensions image show-send actions-ref active-panel set-active-panel] - [rn/view {:style (styles/input-container)} + [actions extensions image show-send actions-ref active-panel set-active-panel contact-request] + [rn/view {:style (styles/input-container contact-request)} [send-image] [rn/view {:style styles/input-row} [text-input {:chat-id chat-id @@ -370,7 +373,8 @@ [rn/view {:ref send-ref :style (when-not show-send {:width 0 :right -100})} (when send [send-button #(do (clear-input chat-id refs) - (re-frame/dispatch [:chat.ui/send-current-message]))])] + (re-frame/dispatch [:chat.ui/send-current-message])) + contact-request])] ;;STICKERS and AUDIO buttons (when-not @(re-frame/subscribe [:chats/edit-message]) diff --git a/src/status_im/ui/screens/chat/components/style.cljs b/src/status_im/ui/screens/chat/components/style.cljs index 148f871294..aee891ec76 100644 --- a/src/status_im/ui/screens/chat/components/style.cljs +++ b/src/status_im/ui/screens/chat/components/style.cljs @@ -11,14 +11,15 @@ :align-items :flex-end :flex-direction :row}) -(defn input-container [] +(defn input-container [contact-request] {:background-color (:ui-01 @colors/theme) :flex 1 - :border-top-left-radius 16 - :border-top-right-radius 16 - :border-bottom-right-radius 4 - :border-bottom-left-radius 16 - :margin-horizontal 8}) + :height (when contact-request 44) + :border-top-left-radius (if contact-request 8 16) + :border-top-right-radius (if contact-request 8 16) + :border-bottom-right-radius (if contact-request 8 4) + :border-bottom-left-radius (if contact-request 8 16) + :margin-horizontal (when contact-request 8)}) (def input-row {:flex-direction :row @@ -34,7 +35,7 @@ (when platform/ios? {:padding-top 2}))) -(defn text-input [] +(defn text-input [contact-request] (merge typography/font-regular typography/base {:flex 1 @@ -46,8 +47,8 @@ :padding-horizontal 12} (if platform/android? {:padding-vertical 2} - {:padding-top 2 - :padding-bottom 6}))) + {:padding-top (if contact-request 10 2) + :padding-bottom (if contact-request 5 6)}))) (defn actions-wrapper [show-send] (merge @@ -91,6 +92,11 @@ :padding-horizontal 10 :flex 1}) +(defn contact-request-content [] + {:flex 1 + :flex-direction :row + :justify-content :space-between}) + (defn close-button [] {:margin-top 3}) @@ -98,11 +104,11 @@ {:margin-vertical 4 :margin-horizontal 5}) -(defn send-message-container [] +(defn send-message-container [contact-request] {:background-color (:interactive-01 @colors/theme) :width 26 - :height 26 - :border-radius 13 + :height (if contact-request 44 26) + :border-radius (if contact-request 22 13) :justify-content :center :align-items :center}) diff --git a/src/status_im/ui/screens/chat/message/message.cljs b/src/status_im/ui/screens/chat/message/message.cljs index d31ce19d26..5aab7e7fbb 100644 --- a/src/status_im/ui/screens/chat/message/message.cljs +++ b/src/status_im/ui/screens/chat/message/message.cljs @@ -621,6 +621,49 @@ [message.audio/message-content message] [message-status message]]]]] reaction-picker]))) +(defn contact-request-status-pending [] + [react/view {:style {:flex-direction :row}} + [quo/text {:style {:margin-right 5.27} + :weight :medium + :color :secondary} + (i18n/label :t/contact-request-pending)] + [react/activity-indicator {:animating true + :size :small + :color colors/gray}]]) + +(defn contact-request-status-accepted [] + [quo/text {:style {:color colors/green} + :weight :medium} + (i18n/label :t/contact-request-accepted)]) + +(defn contact-request-status-declined [] + [quo/text {:style {:color colors/red} + :weight :medium} + (i18n/label :t/contact-request-declined)]) + +(defn contact-request-status-label [state] + [react/view {:style (style/contact-request-status-label state)} + (case state + constants/contact-request-message-state-pending [contact-request-status-pending] + constants/contact-request-message-state-accepted [contact-request-status-accepted] + constants/contact-request-message-state-declined [contact-request-status-declined])]) + +(defmethod ->message constants/content-type-contact-request + [{:keys [outgoing] :as message} _] + [react/view {:style (style/content-type-contact-request outgoing)} + [react/image {:source (resources/get-image :hand-wave) + :style {:width 112 + :height 97}}] + [quo/text {:style {:margin-top 6} + :weight :bold + :size :large} + (i18n/label :t/contact-request)] + [react/view {:style {:padding-horizontal 16}} + [quo/text {:style {:margin-top 2 + :margin-bottom 14}} + (get-in message [:content :text])]] + [contact-request-status-label (:contact-request-state message)]]) + (defmethod ->message :default [message] [message-content-wrapper message [unknown-content-type message]]) diff --git a/src/status_im/ui/screens/chat/pinned_messages.cljs b/src/status_im/ui/screens/chat/pinned_messages.cljs index 41dc2a0d30..2e7cc0c848 100644 --- a/src/status_im/ui/screens/chat/pinned_messages.cljs +++ b/src/status_im/ui/screens/chat/pinned_messages.cljs @@ -116,4 +116,4 @@ [connectivity/loading-indicator] [pinned-messages-view {:chat chat :pan-responder pan-responder - :space-keeper space-keeper}]])))) \ No newline at end of file + :space-keeper space-keeper}]])))) diff --git a/src/status_im/ui/screens/chat/styles/main.cljs b/src/status_im/ui/screens/chat/styles/main.cljs index c6f0256996..f037a9d1d8 100644 --- a/src/status_im/ui/screens/chat/styles/main.cljs +++ b/src/status_im/ui/screens/chat/styles/main.cljs @@ -53,8 +53,7 @@ {:flex 1 :flex-direction :column :justify-content :center - :align-items :center - :height 324} + :align-items :center} {:flex 1 :flex-direction :column :justify-content :center @@ -148,3 +147,10 @@ {:font-size 13 :line-height 18 :text-align :center}) + +(def contact-request + {:width "100%" + :justify-content :center + :align-items :center + :border-top-width 1 + :border-color colors/gray-transparent-10}) diff --git a/src/status_im/ui/screens/chat/styles/message/message.cljs b/src/status_im/ui/screens/chat/styles/message/message.cljs index 80dcdf2849..841434e593 100644 --- a/src/status_im/ui/screens/chat/styles/message/message.cljs +++ b/src/status_im/ui/screens/chat/styles/message/message.cljs @@ -435,3 +435,32 @@ :border-bottom-left-radius 10 :border-bottom-right-radius 10 :border-color colors/gray-lighter}) + +(defn contact-request-status-label [state] + {:width 136 + :border-radius 8 + :flex 1 + :justify-content :center + :align-items :center + :background-color (when (= :retry state) + colors/blue-light) + :border-width 1 + :border-color (case state + constants/contact-request-message-state-accepted colors/green-transparent-10 + constants/contact-request-message-state-declined colors/red-light + constants/contact-request-message-state-pending colors/gray-lighter) + :padding-vertical 10 + :padding-horizontal 16}) + +(defn content-type-contact-request [outgoing] + {:width 168 + :min-height 224.71 + :border-radius 8 + :border-width 1 + :border-color colors/gray-lighter + :align-items :center + :padding-bottom 10 + :margin-vertical 4 + :align-self (if outgoing :flex-end :flex-start) + :margin-right (if outgoing 8 0) + :margin-left (if outgoing 0 8)}) diff --git a/src/status_im/ui/screens/chat/views.cljs b/src/status_im/ui/screens/chat/views.cljs index 2698d66098..420f6d1708 100644 --- a/src/status_im/ui/screens/chat/views.cljs +++ b/src/status_im/ui/screens/chat/views.cljs @@ -10,6 +10,7 @@ [status-im.ui.components.list.views :as list] [status-im.ui.screens.chat.components.reply :as reply] [status-im.ui.screens.chat.components.edit :as edit] + [status-im.ui.screens.chat.components.contact-request :as contact-request] [status-im.ui.components.react :as react] [quo.animated :as animated] [quo.react-native :as rn] @@ -35,7 +36,8 @@ [status-im.utils.utils :as utils] [status-im.ui.screens.chat.sheets :as sheets] [status-im.utils.debounce :as debounce] - [status-im.navigation.state :as navigation.state])) + [status-im.navigation.state :as navigation.state] + [status-im.react-native.resources :as resources])) (defn invitation-requests [chat-id admins] (let [current-pk @(re-frame/subscribe [:multiaccount/public-key]) @@ -62,20 +64,45 @@ {:color colors/blue}] [react/i18n-text {:style style/add-contact-text :key :add-to-contacts}]]])) +(defn contact-request [] + (let [contact-request @(re-frame/subscribe [:chats/sending-contact-request])] + [react/view {:style style/contact-request} + [react/image {:source (resources/get-image :hand-wave) + :style {:width 112 + :height 96.71 + :margin-top 17}}] + [quo/text {:style {:margin-top 14} + :weight :bold + :size :large} + (i18n/label :t/say-hi)] + [quo/text {:style {:margin-top 2 + :margin-bottom 14}} + (i18n/label :t/send-contact-request-message)] + (when-not contact-request + [react/view {:style {:padding-horizontal 16 + :padding-bottom 8}} + [quo/button + {:style {:width "100%"} + :accessibility-label :contact-request--button + :on-press #(re-frame/dispatch [:chat.ui/send-contact-request])} + (i18n/label :t/contact-request)]])])) + (defn chat-intro [{:keys [chat-id chat-name chat-type group-chat invitation-admin + mutual-contact-requests-enabled? contact-name color loading-messages? no-messages? + contact-request-state emoji]}] [react/view {:style (style/intro-header-container loading-messages? no-messages?) :accessibility-label :history-chat} ;; Icon section - [react/view {:style {:margin-top 42 + [react/view {:style {:margin-top 52 :margin-bottom 24}} [chat-icon.screen/emoji-chat-intro-icon-view chat-name chat-id group-chat emoji @@ -100,12 +127,28 @@ (str (i18n/label :t/empty-chat-description-one-to-one) - contact-name)])]) + contact-name)]) + (when + (and + mutual-contact-requests-enabled? + (= chat-type constants/one-to-one-chat-type) + (or + (= contact-request-state constants/contact-request-state-none) + (= contact-request-state constants/contact-request-state-received) + (= contact-request-state constants/contact-request-state-dismissed))) + [contact-request])]) (defn chat-intro-one-to-one [{:keys [chat-id] :as opts}] - (let [contact-names @(re-frame/subscribe + (let [contact @(re-frame/subscribe + [:contacts/contact-by-identity chat-id]) + mutual-contact-requests-enabled? @(re-frame/subscribe [:mutual-contact-requests/enabled?]) + contact-names @(re-frame/subscribe [:contacts/contact-two-names-by-identity chat-id])] - [chat-intro (assoc opts :contact-name (first contact-names))])) + [chat-intro (assoc opts + :mutual-contact-requests-enabled? mutual-contact-requests-enabled? + :contact-name (first contact-names) + :contact-request-state (or (:contact-request-state contact) + constants/contact-request-state-none))])) (defn chat-intro-header-container [{:keys [group-chat invitation-admin @@ -299,9 +342,23 @@ :edit-enabled edit-enabled :in-pinned-view? in-pinned-view?})) -(defn messages-view [{:keys [chat bottom-space pan-responder space-keeper show-input?]}] - (let [{:keys [group-chat chat-id public? community-id admins]} chat - messages @(re-frame/subscribe [:chats/raw-chat-messages-stream chat-id])] +(defn messages-view [{:keys [chat + bottom-space + pan-responder + mutual-contact-requests-enabled? + space-keeper + show-input?]}] + (let [{:keys [group-chat chat-type chat-id public? community-id admins]} chat + + messages @(re-frame/subscribe [:chats/raw-chat-messages-stream chat-id]) + one-to-one? (= chat-type constants/one-to-one-chat-type) + contact-added? (when one-to-one? @(re-frame/subscribe [:contacts/contact-added? chat-id])) + should-send-contact-request? + (and + mutual-contact-requests-enabled? + one-to-one? + (not contact-added?))] + ;;do not use anonymous functions for handlers [list/flat-list (merge @@ -310,7 +367,8 @@ :ref list-ref :header [list-header chat] :footer [list-footer chat] - :data messages + :data (when-not should-send-contact-request? + messages) :render-data (get-render-data {:group-chat group-chat :chat-id chat-id :public? public? @@ -385,6 +443,7 @@ (let [{:keys [chat-id show-input? group-chat admins invitation-admin] :as chat} ;;we want to react only on these fields, do not use full chat map here @(re-frame/subscribe [:chats/current-chat-chat-view]) + mutual-contact-requests-enabled? @(re-frame/subscribe [:mutual-contact-requests/enabled?]) max-bottom-space (max @bottom-space @panel-space)] [:<> [topbar] @@ -392,11 +451,12 @@ (when chat-id (if group-chat [invitation-requests chat-id admins] - [add-contact-bar chat-id])) + (when-not mutual-contact-requests-enabled? [add-contact-bar chat-id]))) ;;MESSAGES LIST [messages-view {:chat chat :bottom-space max-bottom-space :pan-responder pan-responder + :mutual-contact-requests-enabled? mutual-contact-requests-enabled? :space-keeper space-keeper :show-input? show-input?}] (when (and group-chat invitation-admin) @@ -421,7 +481,8 @@ {:chat-id chat-id :active-panel @active-panel :set-active-panel set-active-panel - :text-input-ref text-input-ref}]] + :text-input-ref text-input-ref}] + [contact-request/contact-request-message-auto-focus-wrapper text-input-ref]] [bottom-sheet @active-panel]])])))) (defn chat [] diff --git a/src/status_im/ui/screens/home/views/inner_item.cljs b/src/status_im/ui/screens/home/views/inner_item.cljs index c816e79b26..a5eb011d21 100644 --- a/src/status_im/ui/screens/home/views/inner_item.cljs +++ b/src/status_im/ui/screens/home/views/inner_item.cljs @@ -82,6 +82,7 @@ [preview-label :t/no-messages] (and (or (= constants/content-type-text content-type) + (= constants/content-type-contact-request content-type) (= constants/content-type-emoji content-type) (= constants/content-type-command content-type)) (not (string/blank? (:text content)))) diff --git a/src/status_im/ui/screens/notifications_center/styles.cljs b/src/status_im/ui/screens/notifications_center/styles.cljs index 295ba77722..5b36b65a25 100644 --- a/src/status_im/ui/screens/notifications_center/styles.cljs +++ b/src/status_im/ui/screens/notifications_center/styles.cljs @@ -62,9 +62,9 @@ (def notification-content-container {:flex 1}) -(def photo-container +(defn photo-container [has-header?] {:position :absolute - :top 12 + :top (if has-header? 37 12) :left 16}) (defn title-text [title-text-width] diff --git a/src/status_im/ui/screens/notifications_center/views.cljs b/src/status_im/ui/screens/notifications_center/views.cljs index 3bd8d4f46e..55323b9c28 100644 --- a/src/status_im/ui/screens/notifications_center/views.cljs +++ b/src/status_im/ui/screens/notifications_center/views.cljs @@ -33,7 +33,11 @@ {:on-press (fn [] (if @selecting (on-change) - (re-frame/dispatch [:accept-activity-center-notification-and-open-chat id]))) + ;; We don't dispatch on contact requests unless + ;; accepted + (when (or (not= type constants/activity-center-notification-type-contact-request) + (= constants/contact-request-message-state-accepted (get-in home-item [:message :contact-request-state]))) + (re-frame/dispatch [:accept-activity-center-notification-and-open-chat id])))) :on-long-press #(do (reset! selecting true) (when-not (= type constants/activity-center-notification-type-mention) (swap! selected-items conj id)))}]]]))) (defn filter-item [] diff --git a/src/status_im/ui/screens/notifications_center/views/notification.cljs b/src/status_im/ui/screens/notifications_center/views/notification.cljs index b66d4c96f5..8fad25cd56 100644 --- a/src/status_im/ui/screens/notifications_center/views/notification.cljs +++ b/src/status_im/ui/screens/notifications_center/views/notification.cljs @@ -2,6 +2,8 @@ (:require [status-im.ui.components.react :as react] [re-frame.core :as re-frame] [quo.core :as quo] + [quo.components.animated.pressable :as animation] + [status-im.i18n.i18n :as i18n] [status-im.ui.screens.notifications-center.styles :as styles] [status-im.utils.handlers :refer [", "owner": "status-im", "repo": "status-go", - "version": "a244d776571cc73ea34d7a700cc5db36166ce832", - "commit-sha1": "a244d776571cc73ea34d7a700cc5db36166ce832", - "src-sha256": "1v057jy565y9178ja8j9j6sg04z83y7a0bnry6ziy9zf2zda7nkg" + "version": "v0.100.0", + "commit-sha1": "1bfde4c4cc69292875ae9fdc41a8b4bd29e95a7a", + "src-sha256": "1nkk7dsqz1x31n305p33jdwpqr9bm7ajkqs3khq5l4ag3njagbrh" } diff --git a/translations/en.json b/translations/en.json index 537a9de213..0962323dcb 100644 --- a/translations/en.json +++ b/translations/en.json @@ -1738,5 +1738,17 @@ "wallet-manage-app-connections": "Manage app connections", "connection-request": "Connection Request", "disconnect": "Disconnect", - "new-ui": "New UI" + "new-ui": "New UI", + "send-contact-request-message": "To start a chat you need to become contacts", + "contact-request": "Contact request", + "say-hi": "Say hi", + "accepted": "Accepted", + "declined": "Declined", + "contact-request": "Contact request", + "contact-request-header": "👋 Contact requests", + "contact-request-declined": "Declined ⓧ", + "contact-request-accepted": "Accepted ✓", + "contact-request-pending": "Pending...", + "removed-from-contacts": "Removed from contacts", + "mutual-contact-requests": "Mutual contact requests" }