From ace355515abc2d2809a50089890f4134b9f5df4c Mon Sep 17 00:00:00 2001 From: Roman Volosovskyi Date: Tue, 7 Feb 2017 12:56:39 +0200 Subject: [PATCH] public group chat --- .../res/drawable-hdpi/icon_private_group.png | Bin 0 -> 647 bytes .../drawable-hdpi/icon_private_group_big.png | Bin 0 -> 1364 bytes .../res/drawable-hdpi/icon_public_group.png | Bin 0 -> 621 bytes .../drawable-hdpi/icon_public_group_big.png | Bin 0 -> 1175 bytes .../res/drawable-mdpi/icon_private_group.png | Bin 0 -> 367 bytes .../drawable-mdpi/icon_private_group_big.png | Bin 0 -> 875 bytes .../res/drawable-mdpi/icon_public_group.png | Bin 0 -> 393 bytes .../drawable-mdpi/icon_public_group_big.png | Bin 0 -> 654 bytes .../res/drawable-xhdpi/icon_private_group.png | Bin 0 -> 793 bytes .../drawable-xhdpi/icon_private_group_big.png | Bin 0 -> 1491 bytes .../res/drawable-xhdpi/icon_public_group.png | Bin 0 -> 751 bytes .../drawable-xhdpi/icon_public_group_big.png | Bin 0 -> 1406 bytes .../drawable-xxhdpi/icon_private_group.png | Bin 0 -> 1166 bytes .../icon_private_group_big.png | Bin 0 -> 2664 bytes .../res/drawable-xxhdpi/icon_public_group.png | Bin 0 -> 1148 bytes .../drawable-xxhdpi/icon_public_group_big.png | Bin 0 -> 2109 bytes .../drawable-xxxhdpi/icon_private_group.png | Bin 0 -> 1603 bytes .../icon_private_group_big.png | Bin 0 -> 3171 bytes .../drawable-xxxhdpi/icon_public_group.png | Bin 0 -> 1526 bytes .../icon_public_group_big.png | Bin 0 -> 2864 bytes externs/externs.js | 11 ++- .../icon_private_group.imageset/Contents.json | 23 ++++++ .../con_group_chat-1.png | Bin 0 -> 1166 bytes .../con_group_chat-2.png | Bin 0 -> 1603 bytes .../con_group_chat.png | Bin 0 -> 793 bytes .../Contents.json | 23 ++++++ .../icon_private_group_big-1.png | Bin 0 -> 2664 bytes .../icon_private_group_big-2.png | Bin 0 -> 3171 bytes .../icon_private_group_big.png | Bin 0 -> 1491 bytes .../icon_public_group.imageset/Contents.json | 23 ++++++ .../icon_public_group-1.png | Bin 0 -> 1148 bytes .../icon_public_group-2.png | Bin 0 -> 1526 bytes .../icon_public_group.png | Bin 0 -> 751 bytes .../Contents.json | 23 ++++++ .../icon_public_group_big-1.png | Bin 0 -> 2109 bytes .../icon_public_group_big-2.png | Bin 0 -> 2864 bytes .../icon_public_group_big.png | Bin 0 -> 1406 bytes src/status_im/android/core.cljs | 4 +- src/status_im/android/platform.cljs | 27 +++--- src/status_im/chat/handlers.cljs | 46 ++++++----- src/status_im/chat/handlers/send_message.cljs | 77 ++++++++++++------ src/status_im/chat/styles/message.cljs | 6 +- src/status_im/chat/styles/screen.cljs | 7 +- src/status_im/chat/views/actions.cljs | 37 +++++---- src/status_im/chat/views/message.cljs | 25 +++--- src/status_im/chat/views/toolbar_content.cljs | 43 ++++++---- src/status_im/chats_list/screen.cljs | 9 +- src/status_im/chats_list/styles.cljs | 55 ++++++++----- .../chats_list/views/inner_item.cljs | 30 ++++--- src/status_im/components/text_field/view.cljs | 43 +++++++--- src/status_im/contacts/styles.cljs | 4 + .../contacts/views/contact_list.cljs | 39 +++++---- src/status_im/data_store/realm/chats.cljs | 29 ++++--- .../realm/schemas/account/core.cljs | 9 +- .../realm/schemas/account/v4/chat.cljs | 42 ++++++++++ .../realm/schemas/account/v4/core.cljs | 32 ++++++++ .../realm/schemas/account/v4/message.cljs | 38 +++++++++ src/status_im/group_settings/screen.cljs | 5 +- src/status_im/ios/core.cljs | 4 +- src/status_im/ios/platform.cljs | 27 +++--- src/status_im/new_group/handlers.cljs | 46 ++++++++++- .../{screen.cljs => screen_private.cljs} | 2 +- src/status_im/new_group/screen_public.cljs | 65 +++++++++++++++ src/status_im/new_group/styles.cljs | 25 ++++-- src/status_im/new_group/validations.cljs | 4 + src/status_im/protocol/core.cljs | 30 ++++--- src/status_im/protocol/group.cljs | 29 +++++-- src/status_im/protocol/handlers.cljs | 17 ++-- src/status_im/protocol/message.cljs | 2 +- src/status_im/protocol/web3/public_group.cljs | 7 ++ src/status_im/translations/en.cljs | 5 ++ 71 files changed, 736 insertions(+), 237 deletions(-) create mode 100644 android/app/src/main/res/drawable-hdpi/icon_private_group.png create mode 100644 android/app/src/main/res/drawable-hdpi/icon_private_group_big.png create mode 100644 android/app/src/main/res/drawable-hdpi/icon_public_group.png create mode 100644 android/app/src/main/res/drawable-hdpi/icon_public_group_big.png create mode 100644 android/app/src/main/res/drawable-mdpi/icon_private_group.png create mode 100644 android/app/src/main/res/drawable-mdpi/icon_private_group_big.png create mode 100644 android/app/src/main/res/drawable-mdpi/icon_public_group.png create mode 100644 android/app/src/main/res/drawable-mdpi/icon_public_group_big.png create mode 100644 android/app/src/main/res/drawable-xhdpi/icon_private_group.png create mode 100644 android/app/src/main/res/drawable-xhdpi/icon_private_group_big.png create mode 100644 android/app/src/main/res/drawable-xhdpi/icon_public_group.png create mode 100644 android/app/src/main/res/drawable-xhdpi/icon_public_group_big.png create mode 100644 android/app/src/main/res/drawable-xxhdpi/icon_private_group.png create mode 100644 android/app/src/main/res/drawable-xxhdpi/icon_private_group_big.png create mode 100644 android/app/src/main/res/drawable-xxhdpi/icon_public_group.png create mode 100644 android/app/src/main/res/drawable-xxhdpi/icon_public_group_big.png create mode 100644 android/app/src/main/res/drawable-xxxhdpi/icon_private_group.png create mode 100644 android/app/src/main/res/drawable-xxxhdpi/icon_private_group_big.png create mode 100644 android/app/src/main/res/drawable-xxxhdpi/icon_public_group.png create mode 100644 android/app/src/main/res/drawable-xxxhdpi/icon_public_group_big.png create mode 100644 ios/StatusIm/Images.xcassets/icon_private_group.imageset/Contents.json create mode 100644 ios/StatusIm/Images.xcassets/icon_private_group.imageset/con_group_chat-1.png create mode 100644 ios/StatusIm/Images.xcassets/icon_private_group.imageset/con_group_chat-2.png create mode 100644 ios/StatusIm/Images.xcassets/icon_private_group.imageset/con_group_chat.png create mode 100644 ios/StatusIm/Images.xcassets/icon_private_group_big.imageset/Contents.json create mode 100644 ios/StatusIm/Images.xcassets/icon_private_group_big.imageset/icon_private_group_big-1.png create mode 100644 ios/StatusIm/Images.xcassets/icon_private_group_big.imageset/icon_private_group_big-2.png create mode 100644 ios/StatusIm/Images.xcassets/icon_private_group_big.imageset/icon_private_group_big.png create mode 100644 ios/StatusIm/Images.xcassets/icon_public_group.imageset/Contents.json create mode 100644 ios/StatusIm/Images.xcassets/icon_public_group.imageset/icon_public_group-1.png create mode 100644 ios/StatusIm/Images.xcassets/icon_public_group.imageset/icon_public_group-2.png create mode 100644 ios/StatusIm/Images.xcassets/icon_public_group.imageset/icon_public_group.png create mode 100644 ios/StatusIm/Images.xcassets/icon_public_group_big.imageset/Contents.json create mode 100644 ios/StatusIm/Images.xcassets/icon_public_group_big.imageset/icon_public_group_big-1.png create mode 100644 ios/StatusIm/Images.xcassets/icon_public_group_big.imageset/icon_public_group_big-2.png create mode 100644 ios/StatusIm/Images.xcassets/icon_public_group_big.imageset/icon_public_group_big.png create mode 100644 src/status_im/data_store/realm/schemas/account/v4/chat.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/v4/core.cljs create mode 100644 src/status_im/data_store/realm/schemas/account/v4/message.cljs rename src/status_im/new_group/{screen.cljs => screen_private.cljs} (98%) create mode 100644 src/status_im/new_group/screen_public.cljs create mode 100644 src/status_im/protocol/web3/public_group.cljs diff --git a/android/app/src/main/res/drawable-hdpi/icon_private_group.png b/android/app/src/main/res/drawable-hdpi/icon_private_group.png new file mode 100644 index 0000000000000000000000000000000000000000..a6f4aa04d6ec48e66ff526989311cb18b8603ddf GIT binary patch literal 647 zcmV;20(kw2P)Px%K}keGR7ef&R8448K@gtVml!MF#NXD7AbJvt0nfpL8brkQU=1<7i{QZ)>A{1C z6h*9vprX*%KPox&lExwk)?D=P@K6it)m{QsX_Z)G^LCs`S@V*8ia!T0*>{+kZ@=Ad zn3;V5t<|c)zg7VM_JUmQ>EYC{%DR)YtL)vB&@5#fWAk}$)54q5bI_0@O*ee>J$G{E zqS+TK2>{{gAhz!7bTeiNeEd{8PXq@Ik%+hgI5d(g>@e7$SW7??9%#ORMIum9`wbqC z$JYSqp^58Ojo1Bk&k|5b^UWk~Ts7uIUk7n#YxEpX$Q=M&V*8FcgMF!Ew}Kq;ttpZo zd{`+JO_}&04+;(RrH)^3KKwheB_M~)6alIB2&rP&6x9-0Ug{#y`*=jx90l{cceWK1 zi9|Ih94Zhbg!%6H>wvJc2-Nc-0)tA?%do4g_uQ~BHPyD h2fJc{E#SXY;5)ld)#=tZ+_eAz002ovPDHLkV1mC^ELH#j literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-hdpi/icon_private_group_big.png b/android/app/src/main/res/drawable-hdpi/icon_private_group_big.png new file mode 100644 index 0000000000000000000000000000000000000000..27fcdf8a2eee17a7f1925f3241c5f4490cef251c GIT binary patch literal 1364 zcmV-a1*`grP)Px)4oO5oR9Fe^R$XXZMHHShce~ppO-&KgY<5#=u`1GsAPrPRDN4bBASf-`1cc_V zZQN|~;&YxV`jTuyn>2r5HB=(vOR*2uClNtIZ9!?Z)j)T%iS?&xW76(sXU218cW!R( z=I$n?eNZy6J7?y6=ghh1Z-%jrvEhOLnFruud{67?KZ2RX)LRVHUaeojq^~q^cBt*K znPTUy*&sRuQmM*dRp?6hAxL{EZiyuhNu>srV%wY;0CtN59375^C!G6kx~M_Tz41n= z-~?l;CMTQ*fOCOO{`OPtm9tKTExj{!f{AaLQkHYyrU8V-tmlS1gWubGE`qz(E0)bY z@jj{8M-F3%?^jB_o=T^FYKz5pI|U>Y1I8Hi$dACS2K_@?wl2uKbI3!Tu;Ab9+ckKsie%W)f!WIRz07a; zVPyNGhW~?h*OD@NdEfP;L^?dT=OfAuORcd$E z7&HgiRbveCa`ewc6Gmh8BLC0ZAeO5Tl##y8@0vu;#vjIwDk-F{q!I{RqpzoZOz5Y{ zD+ZIJpVDi@Xsltn<^l$}kVTdh0*uwgEKHRxrIxKKTyus#Kd>O~AW9TJ8JoM5Y%)xQ}Lt5jJ#|cwlcpJp|DI+HtYq&8z z9Y4~OxI|@*RaQzoz@)Bj4_-1j3a16^F!da>XJ*M#bPg^h!8)uxDd*8+JeIf*x`zTz%?7PUd1ue9ig}(2 zE14-LIpDteav4bUc5Rz0rsshf)Y6lv6~NxcZuth*n7Q{{=R+K`_A^Vd4~M(Lb}=|X zo(6SIsFL~VM7;!Fhc&zl``K1(vVP8BWTY!})+lL>C3grZKE{stg4tWkj0b;hajS7C zT7AQb&ohV)kW!pb0Iy*pZ&?Y3KmCC%PYxWf&}H2eOT3K6ewzQ(fPYYS3VYJLmRG7A zubZ8D`lvks92|{?v2kX{3WKPtGARe~j?%F=ATx6gZ6nd}5Urd0XLm}mbP+>TL2K+u z^Vn;~rNu|bBGq=YB%T>Z`jdOPkWKgj4fYwp=D4-#*^x-q6ybaZ+|m=T7fPPN_}gz8 zYJ7Nie}N6{x&S^Gjs!2TXjVdr%$RKqK*F;4fuTtCRikgUIcMl(Ykx8(g#1#s68s?4 zHH!F`NJe{z^5sr)dI|yC^(Md%+{fM=ekc43t=)sZlx2i@WTkzU|CynV?Z3Klh1N|c zZ$6>$O@$bJB{82>M+WPw<90I9=rHC=DKFXYWegnx8FA1YhF^4My~dF2XnW;#bO%2E zvcu@q24QFp7zTpgFLWDg9I$-`k1xVOL$7z{U=7$ZIi1-YQtENd(C-=kJKkaYZ6FfL z@-2>b1iv$Tc$EZkml8Rnn5=N)4X)UXvY4KvL;12g9Z9W)vC$|c&g)l}Q=1T%aan7& z5R@hiDPodc$io|8u^AuiW?<+Sh|Y$Lv(F7<)fuv2n+JTtrXLugJ|R`Q$}ph;n_M%x z?^UE9$vXr1<+09CuHex#gzuYf!v|~qs`xww-W%93Z=-NF literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-hdpi/icon_public_group.png b/android/app/src/main/res/drawable-hdpi/icon_public_group.png new file mode 100644 index 0000000000000000000000000000000000000000..321c95591c78c11884e5d479e04cdd432bae9d33 GIT binary patch literal 621 zcmV-z0+RiSP)Px%CrLy>R7ef&RKIH!Q4pSacWdwvBOz%N6+uOVO)Mn~Nnya8f{l^$&LcsCe}F+P zZ6uvd8Y}NKIfH8Z|PAxfG+AVr8a7Afw|+q`?@Omd5x+fB}#HbREoee>qW z_q{jo?Evgag9=~+{~x<^h3Q8?cr%7-IGeuo&QDan(#$wDHJ>1&4Gbh00ivVEnBgE+ zJUD5jJI+i;*~4xkV{@$iW9@s_^NE>ztUo4#eH-}*EkT?e2?_=GxF)hWnE}x*R?OL8 zG7!jfaEq;O5+azKe1Ev2*GDp=p_Hh~qH5;|l9v{}o@@ZB3j z1iOdWIU`JDXO0P;%3N-i zSJgHjzRmYi#&c{AEly(VC6b`*E%)UM%g^!??(ASDc|DctTjj);wHI=)KO9oUQa9J} zLL8J^4;q|D5)h~|P_+#Zt~w6I1_rR|Cyl>wFIG#XiaC;)9qR3!_U&BCMc&zILRj=| zGDdC_6V_*O%J2VEzwH-Y#Bo0D*M^>up^s{{bbr%Y`&!tK3U0R@Xnh#8Z`)0C>C)6pRkM1M)TIsXEMpJL9i%2vP2RXhu9sB`V4o=Q@oQ0(sXKKxO8_j z>Bis^zwHjhDeag$<_L%NFn&7{eNk~7%chcZ;@^}1qXNGGENQy@0s>Ka00000NkvXX Hu0mjf0HYF^ literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-hdpi/icon_public_group_big.png b/android/app/src/main/res/drawable-hdpi/icon_public_group_big.png new file mode 100644 index 0000000000000000000000000000000000000000..13805eb7f6a550024d554a5e5c8fe51c144ffb41 GIT binary patch literal 1175 zcmV;I1Zew-P)Px(QAtEWR9Fe^SKn{bRTMwx`(3+1oQ@E1YwMDQJ@6xviF?^JQ6E%dVisfEn?cs` zV+eE${sDV7kro6&%BoMs@FIyOnh1%$v>J#JCp?ho1GL|jX~cAM>)PIXIQQG$uKn)2 zuGNW&=}o>l=ic+{bI(2Z#}}a4ni=??WdPT6KF3Z|YnH61iD-ZT27zcd0D1uEj)C}Y zbUg6ITJio7pu^{W_ve?ggB)Z)eGFs|Q}3!l4IGPw0_Rtiv!HH32R|f_SV}(yR2U$M zB@pyPE$1$>9JI9c#ExyTTx9l8%W8u0@coWCSbQE)3`)R(!eX)?2-=GJydZ83k$8r; zSsLeMN+5a?W}8fl1$mi(o?#QODVLsQddbaPjjaGQafvp}S*ep5n%~Fr4P?i52Y`t4 ztaFX?9Oo|q8`~38qmTWe99Onr!VX((~<>})UQb3=yVxqRXH@>>fm%fq&+eqfd*tA!hR|5igQwul?Ct~A)lgs_}W2<4~2Q`X)iXJ;SLW9vyx!}~J70Nw#l>)uMgRp*fD zF(*YqyvB!v$v5|IAn|23FGVntoK{x@AChsy@Fprx)=FoM@FgGbIc=%{MUQsfJaEc- zLxA|Ce32?}0Dau=V>%{94o1SsS>(&p25Fe__Rg;B;bB~KI{!QUDnQCXH01j%c*fce zLLMRsukh{tBwr_vrKPP5Ziqn+kr0rvlKEix?hQgC&NY!R0pk}!zB?Ka0e0}2Th-=zDiQP$%(k6n}ZSm!M+fsI979E?o_%C+jWcg)-= z28ac>%vFwF38+@t zN+)HWD9yZI^;0ueKNEftE;o@Az2zR!&)wsJKI_cAT~dmEMz`5O_%V9if2FKbgQ*J; z0$$<5-lzNsk`aF1z7(0*WEZD;>hkL{qGNCkd^3qCxj$X{w5Tpx*OHCCpY9=1_=#)5 zJ|x*_hIh{ADgtl+S2+t^#c24K>481bqk-FXMR!rE3y`u4hEpSibdhVRh7IoL9rUqF zoVtfPx$DM>^@R5%f1U>F6A#00_8rCa5H|Np=0KLevW6C*=^e6)8XOdpB?3zuw5`p@vM z6DawHfsr95A=>9GNa2FTTj%{}_@4;V#K6p|nHc4M1H@;732xqeh6|{9`v3n7B0#Lc z@Sm{{CikBaD1rm9;1EX%>VG!BXZXmVigwr$(kU%vlW z2lP@fP(T8x;T-dS=K9!JkHa7Za03=D-)8vl&%YL+fE7^u4FfY{MSP^!`h`ok?f?J( zza2<168Oi!%oLm$<+TB9!2BiKEExX(+Y3~{1yjVx%A~^Z@4wyuzyIgK#87BPhL;J^ z-csOLU}X3Q3URn*21dq@2@zg*|Nr}MkD>{g^PfR{;qslD$U;Mu4FHQmXvfvM7?=P6 N002ovPDHLkV1k9tr;Pvr literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-mdpi/icon_private_group_big.png b/android/app/src/main/res/drawable-mdpi/icon_private_group_big.png new file mode 100644 index 0000000000000000000000000000000000000000..f9bb2211371cd7fb405fa7e6d21efb0818b5ff4e GIT binary patch literal 875 zcmV-x1C;!UP)Px&B}qg%_3Zg>IxBb z>Z}y58XC5{bchP^Vo7XNL`0w$FHt0-1-fPwD4M$Ox$m21p8I6m^e(=4S`Q|q> z-~9QW5Zh~$3cx1%b=6wu^nM|uXDoo?eC2P*`MMT(%>cc<=y*9DE(IwLp(4JV&2fdw z%fYlARJTo50pNW^k;-QPLPvz!V6*$7jj?G`0B_q&<{T`91mX!BL>`7RFs;^=X9$va(vgKB+rS37KSV@FQ4X{ zvvYrQUL|klt!(U)#W_t1AW)WBdNs8)=yl%^L|LXAo{zKJGV9zjG6qyt^);19mjWuZ zwh8MrRw7+cvlIO#X8_881zOfa)xOC)f+)*W^XE*v>-UUvL%HTsh|9d0=d;B6Gyb2O z%tpNa>zJ;D*xENKgRPip?Ni5T(hf*O7vmLxu;PT#p6j{8iS|hW>bhpLbYtNZ)pakR z*hLNO3wm86Z0Kp9(h%iMa$cC|$dUm@6#*@NuPb2dR|C{`|8g0Th>u?AMVe_f1{hCs zxQjX)L9g~r_^Hz#KIgYV!3Qb$G|Ti3a;VuSiOpx3IvWUj^RyL~zO`-N_Zh+*qFKo% zWdso3pulh7RGtJHTpu)F*dtN;0pK_7$_I_P&xj&Buou!8UG1274 z@so__Fk?qv(6f6!-jx46x^9edS^Q1z!o-`$W0~hnwD!qSDsw?N`$l*42= zLP4I|2Bo=qXqzf;qPRFPPx$LrFwIR5%gUQ87rvKooud5?h)@QE+l|?C2ntRM4%obFEOp%#IFjqML4xZWg42 z!A(0kR&+@xCqcp0LD9iVTH^O7nvzQkUG>A=z5o7ukK+#bchxw(Y@ak+NAbnY7>qhy z_a^t@zb^t@1aaP}mun2z#GH%uT7c_bO?G|X7EzH1%iZ4Vf(SE_SV*Z_v?n$#K+KP# zn+fOqV@OCxLzSdsbCMf}wEzNM#u?IcEx^iV=Ov^fqCC^M{XWlvs07nE z-mF&&R%Ut%FjfGyEBsm79QIm3NHFu33IaRC)oS5WsbJMm)Cs>Z)4Qb68pxIE9B nxVwMOL#a1sz4SD!_)E+;MSWeWLg18S00000NkvXXu0mjf4Ir%i literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-mdpi/icon_public_group_big.png b/android/app/src/main/res/drawable-mdpi/icon_public_group_big.png new file mode 100644 index 0000000000000000000000000000000000000000..a03f4354660366e393accea9f2ffdb389a1cd490 GIT binary patch literal 654 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xhdpi/icon_public_group_big.png b/android/app/src/main/res/drawable-xhdpi/icon_public_group_big.png new file mode 100644 index 0000000000000000000000000000000000000000..2e9ffa2d52dce11786e32a4d51df9b9b4f6f0c33 GIT binary patch literal 1406 zcmV-^1%djBP)Px)I7vi7RA>e5SWRpjMHHS{JAXwSij=m=Zd?vM6_7#^5{?9-LLe0+q@sYhaKH|! zgi^<*5?qk*6{M2CMi3{l5ErCM2+E}gM1hMJR8fV$O981()=t}qLrI`X9PjWw+iTC- zYwtQFPK7*@JwNZwyzl+Y?7U&DRazEkS)gTsy|e(|E8(&8qHA?|`KVy5TQSWWYE=Cx z&biqro~9`)k|K9a^1zlp@>Cb` z=EKSqZ=rdT`fkNl0orW0GnuF1DhM%yiwnl1ShOI_ZFM{S4gg<9km#uOF0Q1eB0Vd_ z5}GiM!yuQ+?0HX?yLDPM6$s6*+{;!s-uWwIgkaMBUae}$;*4KMfa(Y*-SqiVfd_jQ z;>Y=xMVIS9ME!Pg+$aq})`3#TrQxW+(D==RVs+ypT>G#W;IQZhLg5N{QwRdx-_@B) zoa$b7kzFFw@fjLhD)kXZp7*As0)k~fC-CJJ?JWS#KnB1vUGcG$c1XPve~E9}xpt-( zo;03gCi{?9Q-m0vjrCoWSFTbZJdu7`nC4?L6XX0EEc}H63oD%KiP7Fg8+{i$A}40B zyhn9{EF#tLEHcHzZj|dhDf20bCP)wy|V4&koNBIdig+ce_K^2U3E5io%8~lrj)hd*~(!D;#6{hdR zWe&Gd+r>8->vP0b38=~g#K2kGNyfAJ>vZLWVjuStF^Fr&pvW<{lrc6!D#$Z z*O1|9xTcm?LW6`P1fcspttK&9360>mb}L-3m(aw8P>|5T6vcv9fMisw+MgC#u4^h_ zG1*c|VGh90k6W|`>rzTdiO)TXqSs0(vDa?SN3}y<)^}B)a*@hdB}-$|AFkx{(ueTh zk!xJXek&#Q`FWgumW=kj;AIU@ZmPG?d`!Ea`8!o?oIyN?yiX@pA;qjWt3ZP%jsW~q z=;a>?XcTj^*qHAYINbjoH?jLPJ4f<#cLpP$7JuyYr0DoNmp+C*PBL-U&RxI91s_es zwD0S4m8lJT02W>=PiJg+W~E2&Q+q1HH}FKL`}cKxBGdAo;mRbub(t(J)6k})`PD{V zL@k$>~R<8{TPzdsD%n1F*^OM ze|kjw(;A~XJa_v(wzm2sV!WKk!upm1GVgzBH|znQ-#2Gwa}jtVAASUIeTy#)jiujI z_O*XQV94@fZS_4FJWeaTZ~5kkzLTZlW0Zu4$Csw?aT{q6$TY48jm~iu(eNgw75jR% zGYFlpTvsnK@Jj(zd!y9d!N#@}pjSA&6`jCIa*jfy7M>z)I-sg2cI)MCTOlL^e(l`y z1G%l-5YGE&060K2I;n7;f2p+jW@krwewF!K?Un^v7HC=E|7C%H0rS<=sAWC@GXMYp M07*qoM6N<$f*p{biU0rr literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xxhdpi/icon_private_group.png b/android/app/src/main/res/drawable-xxhdpi/icon_private_group.png new file mode 100644 index 0000000000000000000000000000000000000000..a470555174ba8ab85fc40945c2cf592a346ac8a9 GIT binary patch literal 1166 zcmV;91abR`P)Px(NJ&INRA>e5SY2owRTMsFW|NpLK^mo!6t$>`X)F2=L`Adt3+7V5Z~RGj!&!Nx-JRiCXU}{Rjs20)aMHn;Un0%?v;^P>;zL8ERzEugB zF^V4m(aQ?DwjRNU_wGuZsi&*lf$@AXX)ji1oZv*Xi3r-cQn&E$Sre$tz((r@a%AOl zxsC0IWO^%d&9Y!brmK{IVU#x8HhjXMZ}xMzoD990HHy3aIAdFRpu$h5Y2jq1($#SUzHe}8`!5OekH1(~hsFec1>NofMUR{w$7-F4$ACvidQ zLc{lDJCNf;ngB+0X&Y<6XjE4}nS5kE648^qJkHkGi4*4_>y7RgSwXbYIWT4v&M3VH zh!ri`areF*kN+GL(B;=$B>?Uqz^l9^f3+r8iR?t7&#L0rvYm*lx_fvianuFbicz|R z91weV4xUBOQi$-AA1LPkrD-tQYVZygr6uHoUcE{XJ;^QaW#cRC;dBJxpz2k^_0_Dg zp#+*0)H&HLf~ReuClH8FXY6sV)9n8;|G3*Q6+tNO*)!52sSG--Gm9mcV$f_!=R-&AXW%1jdig0B7~K$Wuc*2fhiA`?0U( zWpdNo5UoM}dU}k3+{$D3@=Hw@nVumXCO7p&PsU;~(`!9$6h5>Gp7-)q=PTXVF`SNn z>a~$}Ae*0#+hiZ&w%_kH_RbOU$Z$IGlE~*XWItE^pve0-H2eN70{Bom9sgdm4@{s` zDs{|N=m-NJ77c=E4q)o-df!lL;Jm9dmM=cahtucmBQTDut1@!Of4F_)x_iYg`PxG&Be$a%?AQ?AQU(G%8U)fQEqDN=@1bl|K-a@S)JCYHOeE7VM-p zwrihvhTmIzkG;K_yIuQiVzeu*XXm{)@4flmo3FQP#=jkEC8xK)VJA^{O6L%az7p9jK5`a`PJ^`vfulWPbZUA zfWG;&p_Nyzh?_YR>!e_7xWR@cGu|#NG+sIIz}oS2j_7zb9sOUCLY|b8cThtb%l^c$sK{0ivOSux-^T#zgcU=A<*Y4^nB@HNvDvHPq}) zprQ>8B^5Z1DDiZ|O{ddot1AN!v5~9dKKvwWRSMzU+1$vA>Z1)G9&-5gN8VjK6`$@! znBV2l5+(H5`WQ)Q7W`N)}!JtcspY zlbe(4b2W`lrL2n>93akS4~Q-$^vLrfX~SR3SLmaIr$@bA#W3AuuU0B1Xv8BK6kbGp3Sbh=v0x4BF>d*2(Ha{SP~nHVr*#S<1+v_M|ICk55AI z2;xi`{z6!f(D6WJm*~V-@eo%^eU!4GV}h~`h_gdU*5avFH>{{F=^$M?J(=i%0g{IC zOO;Zr${(K)v1e#mck`)EbmF_|&a+M*P3)AipaZ8P8?>ahq(irO_|fNkUT~Dr#tz4X z%i6sVHj0w-S0H~0_XaNI%>ZY$(>|%>Y^bOxQjsndvMkdb82@z$>v@lB2PDi55A`;e zb~$xjx$F{V0EZ5%Pa}%9={l8>&e^lQO{Lnys<-{JOS#%ZZ8-jGbfn7L86WlYMQb8o zOgFUB=~y;N`=ALkthYFy%A zYZf3o6FD<;x0Dt#k^EC|yc~e|^LO?|z*{({{gHF?Y;I1@8E+!b3xuxj&!Db#mg%$s z-PJL0uN2}NIIe8*4M-+G02q!u7r0>@Jl4T=`F3C3zbZ5*T`yXa^f(6*`eYu z77ak1EHLsLIvdxFrnBK2pxTaiK5EH$JrnXl#Ai`Dr4A2~G!|jzreiI|Z#p!0S$`x} zHWe3Vk@)(Ao4!=f`0@Ud8!_%W+7Rv2*~|z~bK8{RPgC@W z%J?ie@^^@wQWf7zv-3idUB)#15Aa49GsX=j|4niNLmGeSRdx~lT#qbS1wdCO??~Q# zA(HxYBm5>ENNEA8?ijoguXCUF+X=T}tUP_|qS1=h?R+|!&e)!g;Z@_-#0AhddU@_T zoc{yrzc3^_vo#vMxP3cUW^LVV=$Yol7h+AHI!UtDPxY*7t2ZA9#9 zAJ}GDGfzU1c7E{~Nva}MxnBhi35|=%Ln!p%aDD+%@I9nMUUHNkcOHC{b3pzHqIB=u z+1`H(QZqlms<=hdeB*?iXald>%U4Da-Vof5#Q1X%&Ik_X8G*2W8tgmfy+Irpo)fsqO1boLe&nvczAE1xcU z4936H(^C3FmECO9YTEk0EtuS=((8?)q_-NB`_+L1Wp5Zc=8gD;56lM~az+T5GRBEc z%kAya=#S`mDK4@_HdVH~J|+Q#@8kBU8leZn5rf@ve0Q<(0|aFo53yC^>oO_t^pNc; zR;h>mu28D>L1|=*Y%1HqN88sqW&$8u8nGB{58B+uiyGgmisFC;FWj#>e>g{XBn^T^bDJM zu%=CWmP?Wsrun+|8$!tnl7#Jw9GkQzzV26lYWsyzV4D<-;ZB+xvG>V$G$#N8l7&Fd zp*!UYz`NI}WGpRl8Zzo}&E$1n?WnKD?O%UJ2eKo8txf`${|+(6hqIvms!j)vBQYKC zTB9Ra-gJCQ0EA!ij6xPx(Hc3Q5RA>e5SYL=#RT%%idpFxO6AKNDDAp(!NqSf#tnm*~HlrZ*uqNx&E<{jo z5MX}po`%&{LHlN;4_lrm`>LVobJW=hteE$1Y&G0NZ2apm;H&_vRxN6OAa?{-X zd2;{}HU%D6H}8Lln4MzV*HxCD5N^QK!s$rmlkB)G6xEU(u$k2Dxrkz2>&~I z{RO0h83ari-p~%@a>b`+h&CFCFt)oyrK;A10T5Njw*!MmN~^_^*I>|&@QjitwQ&^{ zK}3094h-gsd&rV6u`m1LkBBLdxIaLO_TkUwk2jF{=*+&(0f1i;-Bf!t_;R2SOF%kgpW~sC4H@cFz;n%tG!UdY4_#8!0y!7)WK_r`2*C$s8_<7YrT~3 z!>Rx6)OncK^?-(PFkgO}a5Z-BLb$js?7NT#?Jfhmk{2=7bqJNbw^5K5-fc8fIQ7KZ zu4UsrJw3A;w7c~7rvAeCSiO?>JwQTu56GPNfLlkHzV8&$%B4E}>DhDB>A`IAG*V`S z4f?UaZ`(*C!#j4oG70+0dZpVhGULvR40QWNh8<3)W#|&f0c{1qAHwezbhnW3`)Hef zG0^-@Nu^R%^hfLU3;ia}$N`}J#|57N|8bq`^>p#-w#P&H;SDv558?|HQjLEVgGcHcKtq1S zq=*&X=}hWFR2Fsq;*7nmuXDf=0{F{LU$;mDo~Zn{*-i8IEsI~rvOOzG-V>!VWYsQY zvqgNcYFw5qGCxG1j^M1BKzr6S>CJb0U%lFxTgNa!$>oN-W|Vyv+?8S)GgmyY?wze$ z=Ug|2hRV-bR67Ia#f|_{WP0VJ#`5}q!Xbxl1Fb+`-}W(htpA92i%^#upFN$;me)H( zy)uV#!*A7C{RG+_@VDprXsf_$eSua$3)neb<53M#kKG0NIu4CvNVRU{*E08Es{Yxv=9vE1->}cWwU-*gtDz5V^h*j=j_fyv@)2aVx=Voq-+DLIdg4K1hD9 z`#y_8_&>p+_l-|}-)wWzz_%nA59P`!eCzxQk?(FQ$8?6o{AeJZ{JAMlgo#KFXuE}i zn3d{@1e0tNmM$n1a1LGetr*3tBWK6 O0000Px+_en%SRCodHTWf4oMHHTM?{*6XDJDX&-6{_u8Xqx2Nw$d+qKQ9@A^yQ15Y)C< z3icHZB{3?A{vjroQY?i&5)l$5Mnwa$8lxe)3u631Kztx1cDHSS1Srt5+r4-EX1m+o z-JQFS?%j65dy|_x_sp4@GvA&$GxwacjM-r2vFut zrmscQAwF}cf1sQ(&CNJ-b7D&&O$jj?!t*?Fc6g?$9&D?>_mWjo<~2Z7yZi5F8h3Mm zL0qq3j2`EVJCaVG*bpOX?rCs!B;`x9GH(E?+r_K(Y03U=wF_ z8E2d0IL~+ppeRMkFZ*grhSQl4%_up^hJA^wL<<>n;9bECK zupJ$B3(i7YtWv;?#4$391L=tFdl$B8eV9(l{<4yix3{mQpph?HP6|+vLLD%~DZ#;V zxsI8iK&M_6w!`6^eSFX6xmTiti09sVOHl3g_|ao7&^CaO89)@$*T?k} z?iAli0i1@{_B6V_8Xu)`yp;b1&JuSu87(ps#dJo*R-4rA=xHpS0LO&sP9d8Dge_S5 zt>kn%Ke|&UpUyl?0m3?+E9;=WcK!t!{Z6Hs17tGeeAuc@M9T>|V}NoZMILu*1C-*& zu>rCHN`XL%YFmSBfKnikqB>&@f?HF3*!^!VbAaH#k)g18&&5SD`fWoS^J&M5E2Bj? zOaX!m3=_=BKjUkK;AtHG5Q{vi0IWgZ&V(^O_U zPwD&&#H0-?clLb)O_Dp!Vmg`dC?YiDaTXMvi1#QO*mG9Q1wf`AMKKFaHaf!GX;$f%Jmlr~KR761bHkAFHP2bZ7kPy1D<;vV4 z8g53&xfYhNIGc%>wFPLGQHQv@08K|(CT%9Jrc z@dJtMj^4rk$GE2d7GIZ>_egdJ&N3dRAP(nrp4WoG#b((Zh{7D}ZY*0hSy{3MC_1p& z`bX^SCm8tU;EUu3MO#eGQ(@H9)#RFV`iuEV+9LU}{-1Odxr$YCtR#gsVh8&axAZf{ zq9Mn-!LNT!WWA0PCQ+EQ@ycW@k$C}raVi>7yAv&*jq4=q+TSiG)pI%dF2)PBS*HS9w#2Y(ZpftG{Ncsf zGI~6%t)2n}jsj$pNiJ;FST4VcT}@IOOA>j~$ZoYF1z2=!89?|P>5r9k>@74Jcvwc4 z(US0oS*Ae>(Gi)n_>irxYV|!Wt25FB zkKi@ZqGg3MBymm8Wf?%oCWFe8mM{(Yu(3lONCr~4PUj!vyp(t@L!U^P_#~mDy<8< zGO`p~^a0!RO8b`iBC~$lE=vItv*@lb{Te6O#;icXauj`ZHI;onZOB9hw$uh0CsVb{ z|2)314@#Gtkuk0efv#~Px){YgYYRCodHSzByWMHrs{oNX72(hGqGRL~$b5~&y~4@OcNluHX##4N478zJ%v znivx00YwshHsL|qEqhAYG#Zc|tF>0es1dw8AcQo=a#aXaMZ3_w%Ova0U=R(LAuHxxVITx_RU@0Enn{boK6F9A09KlD7E(fG}Z!lETs# z)~u-r*@z@1^ zMD|E19C}AKkBln7G)?ct-*^i-e;OE+Qy9~cu}d^pe*hhN9xN*jR8&+%WP=I>%)6q9 zLj=GSSzXYevbCY+bGLeFSHRxAeM>Hk;7R0cHzmA+N_G|jkx%W}1HK&vOb$w2YrNoyO0DhylHp*fHRCjZe`J!sL4|(jfj)1v5nVgl!8A{0~ z>LUXwU1+`1J%*&NQU}=<52ol#;JaCwkJ`5DfMgy3wVT`Lr83I~iJxFSb=x zU9;oa(WC%~^08%PL`vs|Q_Q;>2`|0TcWwb{{m$G}9F)?PN+!mb`*~~=Cr5OpuLJ9( zk#s$ZiLP|!*`3%=)s_Mvm9fdC-b{kwv zL(OY+yzOx-PZe`?YJS17#H*;Ly9YqOWtCNL)??+0t0k9Pi8git8{&_(sxMN!Q?e z0GWrbfM=;cpzEytre22)Zz41Xtc79f;=*Sy|`nte~Yo&queWg;sz1%#u9hUG&H z^#+=sVKmfQ@Fe5f`vu;@exL8LtFkfWBmjnSs5rv4Z3y@r zUAaqKCKaN}>p_pUy{&%LuuC2JZP2aZbmaaSadQhW+$L_2>DZtO8KY5syLejR_S)LV z|4d~gXDXomy}=?F4eh7$mU_@|N{|verg`($Hv3lm>?9-TX#)@l^e&77dxDsSb z8nu};PYY>#yg<(&XUMep`v&s8-7UUl=aL1{8T{~GJ{Ikx$CI*Tav_1jxo-6d3y;wQ=rno&{hE@0z{;DH zKEMcgU~y|*^-p&8T%QBljowA4&V`OJ9@{68yzr^f);NEPRx)f2fXZEqAm5j@iIIWI@v&d))SwhU3~~dRgV+c;6EMFpS>0H19V}N)Q0Y?d*{K1$OkCLZcla z(a!_`q8u9B{@W|jkVAXKmX6|9_uqU7FwXY`061WscxarAKRN+kwoemgO@{rnY%o?V z^S?v;_!U(lpb$_9Cy)5V+M5_#5V>J7@o?(1!p3002ovPDHLkV1mmx B0E7Sl literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xxxhdpi/icon_private_group_big.png b/android/app/src/main/res/drawable-xxxhdpi/icon_private_group_big.png new file mode 100644 index 0000000000000000000000000000000000000000..c839ffa49ca3ffcea3a18b5a3c539681468c1837 GIT binary patch literal 3171 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 literal 0 HcmV?d00001 diff --git a/android/app/src/main/res/drawable-xxxhdpi/icon_public_group_big.png b/android/app/src/main/res/drawable-xxxhdpi/icon_public_group_big.png new file mode 100644 index 0000000000000000000000000000000000000000..6b9a41892c5fabf85b80e8af05d030781821a69a GIT binary patch literal 2864 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 literal 0 HcmV?d00001 diff --git a/externs/externs.js b/externs/externs.js index 98a535df64..bbccb9e30d 100644 --- a/externs/externs.js +++ b/externs/externs.js @@ -202,5 +202,14 @@ var TopLevel = { "IBGLog": function() {}, "getCardId": function() {}, "readTag": function() {}, -"writeTag": function() {} +"writeTag": function() {}, +"Error": function() {}, +"Linking": function() {}, +"reload": function() {}, +"stop": function() {}, +"toLocaleString": function() {}, +"openURL": function() {}, +"Number" : function () {}, +"toAscii" : function () {}, +"toNumber" : function () {} }; diff --git a/ios/StatusIm/Images.xcassets/icon_private_group.imageset/Contents.json b/ios/StatusIm/Images.xcassets/icon_private_group.imageset/Contents.json new file mode 100644 index 0000000000..d65e70d819 --- /dev/null +++ b/ios/StatusIm/Images.xcassets/icon_private_group.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "con_group_chat.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "con_group_chat-1.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "con_group_chat-2.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ios/StatusIm/Images.xcassets/icon_private_group.imageset/con_group_chat-1.png b/ios/StatusIm/Images.xcassets/icon_private_group.imageset/con_group_chat-1.png new file mode 100644 index 0000000000000000000000000000000000000000..a470555174ba8ab85fc40945c2cf592a346ac8a9 GIT binary patch literal 1166 zcmV;91abR`P)Px(NJ&INRA>e5SY2owRTMsFW|NpLK^mo!6t$>`X)F2=L`Adt3+7V5Z~RGj!&!Nx-JRiCXU}{Rjs20)aMHn;Un0%?v;^P>;zL8ERzEugB zF^V4m(aQ?DwjRNU_wGuZsi&*lf$@AXX)ji1oZv*Xi3r-cQn&E$Sre$tz((r@a%AOl zxsC0IWO^%d&9Y!brmK{IVU#x8HhjXMZ}xMzoD990HHy3aIAdFRpu$h5Y2jq1($#SUzHe}8`!5OekH1(~hsFec1>NofMUR{w$7-F4$ACvidQ zLc{lDJCNf;ngB+0X&Y<6XjE4}nS5kE648^qJkHkGi4*4_>y7RgSwXbYIWT4v&M3VH zh!ri`areF*kN+GL(B;=$B>?Uqz^l9^f3+r8iR?t7&#L0rvYm*lx_fvianuFbicz|R z91weV4xUBOQi$-AA1LPkrD-tQYVZygr6uHoUcE{XJ;^QaW#cRC;dBJxpz2k^_0_Dg zp#+*0)H&HLf~ReuClH8FXY6sV)9n8;|G3*Q6+tNO*)!52sSG--Gm9mcV$f_!=R-&AXW%1jdig0B7~K$Wuc*2fhiA`?0U( zWpdNo5UoM}dU}k3+{$D3@=Hw@nVumXCO7p&PsU;~(`!9$6h5>Gp7-)q=PTXVF`SNn z>a~$}Ae*0#+hiZ&w%_kH_RbOU$Z$IGlE~*XWItE^pve0-H2eN70{Bom9sgdm4@{s` zDs{|N=m-NJ77c=E4q)o-df!lL;Jm9dmM=cahtucmBQTDut1@!Of4F_)x_iYg`Px){YgYYRCodHSzByWMHrs{oNX72(hGqGRL~$b5~&y~4@OcNluHX##4N478zJ%v znivx00YwshHsL|qEqhAYG#Zc|tF>0es1dw8AcQo=a#aXaMZ3_w%Ova0U=R(LAuHxxVITx_RU@0Enn{boK6F9A09KlD7E(fG}Z!lETs# z)~u-r*@z@1^ zMD|E19C}AKkBln7G)?ct-*^i-e;OE+Qy9~cu}d^pe*hhN9xN*jR8&+%WP=I>%)6q9 zLj=GSSzXYevbCY+bGLeFSHRxAeM>Hk;7R0cHzmA+N_G|jkx%W}1HK&vOb$w2YrNoyO0DhylHp*fHRCjZe`J!sL4|(jfj)1v5nVgl!8A{0~ z>LUXwU1+`1J%*&NQU}=<52ol#;JaCwkJ`5DfMgy3wVT`Lr83I~iJxFSb=x zU9;oa(WC%~^08%PL`vs|Q_Q;>2`|0TcWwb{{m$G}9F)?PN+!mb`*~~=Cr5OpuLJ9( zk#s$ZiLP|!*`3%=)s_Mvm9fdC-b{kwv zL(OY+yzOx-PZe`?YJS17#H*;Ly9YqOWtCNL)??+0t0k9Pi8git8{&_(sxMN!Q?e z0GWrbfM=;cpzEytre22)Zz41Xtc79f;=*Sy|`nte~Yo&queWg;sz1%#u9hUG&H z^#+=sVKmfQ@Fe5f`vu;@exL8LtFkfWBmjnSs5rv4Z3y@r zUAaqKCKaN}>p_pUy{&%LuuC2JZP2aZbmaaSadQhW+$L_2>DZtO8KY5syLejR_S)LV z|4d~gXDXomy}=?F4eh7$mU_@|N{|verg`($Hv3lm>?9-TX#)@l^e&77dxDsSb z8nu};PYY>#yg<(&XUMep`v&s8-7UUl=aL1{8T{~GJ{Ikx$CI*Tav_1jxo-6d3y;wQ=rno&{hE@0z{;DH zKEMcgU~y|*^-p&8T%QBljowA4&V`OJ9@{68yzr^f);NEPRx)f2fXZEqAm5j@iIIWI@v&d))SwhU3~~dRgV+c;6EMFpS>0H19V}N)Q0Y?d*{K1$OkCLZcla z(a!_`q8u9B{@W|jkVAXKmX6|9_uqU7FwXY`061WscxarAKRN+kwoemgO@{rnY%o?V z^S?v;_!U(lpb$_9Cy)5V+M5_#5V>J7@o?(1!p3002ovPDHLkV1mmx B0E7Sl literal 0 HcmV?d00001 diff --git a/ios/StatusIm/Images.xcassets/icon_private_group.imageset/con_group_chat.png b/ios/StatusIm/Images.xcassets/icon_private_group.imageset/con_group_chat.png new file mode 100644 index 0000000000000000000000000000000000000000..d310e39295698838ec8517cdb81346f05de200f2 GIT binary patch literal 793 zcmV+!1LpjRP)Px%(@8`@R9Fe^R!wLVQ4pTlM2b-;Xb~|Y;-OaXqAh}0)PRaHt%71{nxsh%UPKDs zylGVsJgS9)2NN|3F1@v?}nwR{)z`fbjjKR{)LxQ5OQf1r2Zehn(YxNGh(T3J6D17loip zMj|F33wT}UjCQ%ME8uQ4-7AE+%+hx=c3uNW2)k`G=y2qX$?n9`TTvHph{$U6$+Z=% z-9F#ZXGS0AR1dzJ6S}U?a6$){vz?Fag6IN%$Ucn6$zqH`LHo?eCAN%WzcEIxl>#`C zMgqoFey&Duu9OPM;ARY^fKY6*lYlmw5)d9V`bfhk{H)7HyIji#)GRQg@+k$VfQ@WH zxAQ$BTvg(T#{BMMvnrobK)`+EHE*GLRluSRXJ{g$1JbU`n|3Z z6<*p*cR}c0`Z$4}U`&lj4tUH74{%w9S<>a$Ym!$727Jy3h#Ge;K4Q`Zevq%2^crnm zbGTXLlFzgP)nfi+p2=jab06~_0&$ufco!$`0K(6_YhEzR1lVmM)%&9<0z#2wHwcU} zai^JBCYmF#_=7&@bT!6QKscJ-OS(8i2s;sI2N8bb=6c6PORR6-aI3$+CnpnyBS{Al zr1)4}omf4`l0~DzVNc&g#s8atSZs1rpPgg+fNUvslF9ef3*{d8%3rik5|c0G zd5cn8J-nHZzcmQO;vwl@62QL;=gk6s+4%?K=g>)Psmxb$PxG&Be$a%?AQ?AQU(G%8U)fQEqDN=@1bl|K-a@S)JCYHOeE7VM-p zwrihvhTmIzkG;K_yIuQiVzeu*XXm{)@4flmo3FQP#=jkEC8xK)VJA^{O6L%az7p9jK5`a`PJ^`vfulWPbZUA zfWG;&p_Nyzh?_YR>!e_7xWR@cGu|#NG+sIIz}oS2j_7zb9sOUCLY|b8cThtb%l^c$sK{0ivOSux-^T#zgcU=A<*Y4^nB@HNvDvHPq}) zprQ>8B^5Z1DDiZ|O{ddot1AN!v5~9dKKvwWRSMzU+1$vA>Z1)G9&-5gN8VjK6`$@! znBV2l5+(H5`WQ)Q7W`N)}!JtcspY zlbe(4b2W`lrL2n>93akS4~Q-$^vLrfX~SR3SLmaIr$@bA#W3AuuU0B1Xv8BK6kbGp3Sbh=v0x4BF>d*2(Ha{SP~nHVr*#S<1+v_M|ICk55AI z2;xi`{z6!f(D6WJm*~V-@eo%^eU!4GV}h~`h_gdU*5avFH>{{F=^$M?J(=i%0g{IC zOO;Zr${(K)v1e#mck`)EbmF_|&a+M*P3)AipaZ8P8?>ahq(irO_|fNkUT~Dr#tz4X z%i6sVHj0w-S0H~0_XaNI%>ZY$(>|%>Y^bOxQjsndvMkdb82@z$>v@lB2PDi55A`;e zb~$xjx$F{V0EZ5%Pa}%9={l8>&e^lQO{Lnys<-{JOS#%ZZ8-jGbfn7L86WlYMQb8o zOgFUB=~y;N`=ALkthYFy%A zYZf3o6FD<;x0Dt#k^EC|yc~e|^LO?|z*{({{gHF?Y;I1@8E+!b3xuxj&!Db#mg%$s z-PJL0uN2}NIIe8*4M-+G02q!u7r0>@Jl4T=`F3C3zbZ5*T`yXa^f(6*`eYu z77ak1EHLsLIvdxFrnBK2pxTaiK5EH$JrnXl#Ai`Dr4A2~G!|jzreiI|Z#p!0S$`x} zHWe3Vk@)(Ao4!=f`0@Ud8!_%W+7Rv2*~|z~bK8{RPgC@W z%J?ie@^^@wQWf7zv-3idUB)#15Aa49GsX=j|4niNLmGeSRdx~lT#qbS1wdCO??~Q# zA(HxYBm5>ENNEA8?ijoguXCUF+X=T}tUP_|qS1=h?R+|!&e)!g;Z@_-#0AhddU@_T zoc{yrzc3^_vo#vMxP3cUW^LVV=$Yol7h+AHI!UtDPxY*7t2ZA9#9 zAJ}GDGfzU1c7E{~Nva}MxnBhi35|=%Ln!p%aDD+%@I9nMUUHNkcOHC{b3pzHqIB=u z+1`H(QZqlms<=hdeB*?iXald>%U4Da-Vof5#Q1X%&Ik_X8G*2W8tgmfy+Irpo)fsqO1boLe&nvczAE1xcU z4936H(^C3FmECO9YTEk0EtuS=((8?)q_-NB`_+L1Wp5Zc=8gD;56lM~az+T5GRBEc z%kAya=#S`mDK4@_HdVH~J|+Q#@8kBU8leZn5rf@ve0Q<(0|aFo53yC^>oO_t^pNc; zR;h>mu28D>L1|=*Y%1HqN88sqW&$8u8nGB{58B+uiyGgmisFC;FWj#>e>g{XBn^T^bDJM zu%=CWmP?Wsrun+|8$!tnl7#Jw9GkQzzV26lYWsyzV4D<-;ZB+xvG>V$G$#N8l7&Fd zp*!UYz`NI}WGpRl8Zzo}&E$1n?WnKD?O%UJ2eKo8txf`${|+(6hqIvms!j)vBQYKC zTB9Ra-gJCQ0EA!ij6xT3e}|*wm^T6}x6_TBH1_8Ki1gZ4E^!D%z?&LN!*bpj0E&N@`Ti zN~lq4?-kJ)U%!j*{(FAUd)|xp>YV2}7jMcvOCx3mJ_Y~)z-(e{VExzK{;Ml=f9GOu zxawb{3b8iQ1Jn%*tOEc{KobL9+X$-dhm5bT+w*F#4$T_5+n3NbZea=6vW(E>wT@L5 zK9w)>Z8ys3I6gimdUdr>goGbEmC5kUu#I&GbT!I1YmZglc6^^6-#e{*@8jeHbcw}1 zf_;R88_`QJe1&}8!&20CGMv{IzA}f!42cz}goUB-4?7G7%ZDspMDQ~y8Y&`_T} zsr+Dv&(ALA&vlQ9SAfZ6$_}fdRD9kZi_G@q#=N<@KRBF3cCA%Bg}HLERQj)9G%FLr zKfFsj0}QC$>87Pb8R;*s!pI4G=05ZjEhPEZQ3sL$*uOW0y4dO4xF~)`&n8D74p5|& zynqdL$X%7$5rmhu%QF2Hd(g0zuO6lX>psU=r%82%Hdv<=BL6&)rypzG_!dBTC_SLY z&mq#HC}{Z=MI#|XvL+}T{YKEVo|)}sNRDtMa#7p}ziwn#OTG$}A@N0pp>ya=s+tg! zew)K;BCn4xgm3O{p8aeOL~2@z=cCjiK=M}>X|vi~PcKLgap{Rb(D|A$ z#yDBfrBkz1{Yxsgv{|QFHFb%o`n){9`1o|Ta;Oh?Ol?3k-%#!HKo>o~ zqY+$O3LL9EVm2Ew`JlB~OnL?nIXeU%r=0s3cuus0&EL#CFxu;GH-9RV;k$@y;PNd! zj-&2%L0#m{uP}g>`iGF&^#DYKIsOW)9%{8WhP)-3#hFTzDoXN**4+=nY5a8Tz&b!7 zizmIl-_5L0p~yqbYT_cmHCSODokI%a%)q^}q$TPe{5~F8W?R{3kKj`WMQ26JdT&kg zcm!(RCUr1TT<&f?yDO2WNE+kJdfJ9_nRc*YDn-9-)CV~{6yXSb^7QvuxMTNpubHSP zg1wzSqE8=z&RGl*h6IxC5lxM=Q2sI6Z@YjxPMB1D;1-fBaDz0K-MDB1PnWfO4HOe> ze+H+f(vH{oA_|Ja*%a&-w@W*(z&b1(Os%2sCBz4h$1|t&b5ILRi3==yFO!M5IVP2k zBILx29?rgm%KK)AF|=tWic{1Jc867=RfFnPUBHER+-ts{1Ss%oqwCSZZ;{felWG-) z*#lQ4$P2IwWGy5?fG(A%ilMn0AIo?KuUJbn_ zaWH#xcc1rsN4~!nkaMSI&P2tU(6u7`F-DyH)Nw_fBgCfWE9)GM=3*&S^CRzS|7K|# zoZWv>QL;+X7~*W*n9x%uN^@l7GjQm4`g+aG$om^_NP!HTGsQ2_mEj|_cpmaUS+$K!IF;3H~{ZNJ*ebOLJ%75}mH%Tko9Gw%D zVt)dL1lo9@1q*8Y_xppyc-!d#?5@G+ICRc%z&aE7U9pbQn@DxmavY~AtB~#*E&W>W z%Q5#moY5Ku*Zvixbu=n#n>LI(d?qJOR(>krugD3dj#Oj%ewzdrEScA2&!IU}=^lv! zNXe22PHUSAutK(K8d*v6B*y!&FH-+l-AHJdy%z%LJ?BkDkk0(ZY_oS3elLmGs)TXI zgO5ON;Lo{``q|+W^VLbJ2YsmuB*zxR-7C-kM~YsFP{N*pZCzxm?5^5)lfzW6_04o7 zVauso43Y3H$5ddbokqn@q<*Y9{gCSKZa6i8Tgmpg30WJU;pG zeumU?T&NXEt}pECWBr54Pu>_NOigJ`NJARqo2`PZHQ{@&anh#{cKGt>~__5_>{-8S9RlR>(Q|0qjIV_9Z zxyOyG@dhkjqe^rmO49>ormZ_MZUM0@BHc6amUlL3o;^KNyhpy=KC+2PFJ86<^Ef@{ za(o_=$FTQ62qc=uoDilP^kaH7m)s)Wv+0bft-!hA9`tVJxwO-khJ@X{g{~@-+M!%j zdD$<3Mr4s|0oxcuKAd!1+qL*Raa|TooDo>}F9l6?(rvI!?rJ)0#8gXhjd%YW!9}og zYxKS)Q_(II-58D8SiKRrPV^rnQt@|8-2tnqw{VqlEY`QfhX8BIKkCv`Xk5HD z94Yl?5}BQJJwq&_Q$Kqcf<^h|ljYoOy0B1Y6Af*$~dE z$=^QT&3dwheE6k;$N+!u+Ld?AzNQ+#8_Rfem}gAY^%{z2;_m~Qw3Z`kdCZCtERM8~ zloTFd>4|B3m}Enqra8p;7K7zN`|s>wTy^YgmR5WY%|_Uez@F4vYouR_45 za>=46OUpgj9N#W_@a8*m8hRO%VUcpDY?J>0?*h4S31tpMHCpR&XOo8%_GM5Z~Zr zfLEoka}5V2K$u(pm6qleXGPTI(Ct#~FAhtISLWQc=D0R4C17 zPy>v^6rKvlm@K79ORWXh*QerVY&AJ_MGL;FAa|HT%|hZl&tOP4Kf$2%XXU7lKk}v> z0xt`ScMxz78Cyg5JyG8uZj5DLLE{o#SeQ^_{14l(@o|B;AF-`P!g6xUHbu-=xB3$= z3$?Ub1P(V9!Tk>Xq`DgTo!z^LwKEM=b*#S1XQFOsrv4xQu+KeIn@)e~49|+7(1r>H z4@A1fc>Z>zdwD5E-!!uDvV_N}(@Tjckry%jXZXmnwycK=GDbEo*LwhJ*$ap4uDm-2 zlK62__A~kKIvJdxgoDI;Gr5jN$uxVLANjNBd=~MhQTIfkyHBn^?p7HYZw-~E? zV)czP+d%-jt9^R$*hliYInALKVr4<=k&iObghbEJGpWZ}OXfZ3Yq;;PE>gCW#ZMb} zqqk8(-k+x|RJOH%Gjo}}vP15f{Fk2JjKmbw!4k@YFe6qSrd$YnHw-cvb65P(VXA7~ z1{hO)Cn~N4=j|RW<$kSA)BSJESZu3ag7RjWHP_&8nR}m!KaI^-!xMk>;eP>|$8u!# z2)ouG8+Esb^Mc(!ocs=MjsJwU_WuG1FI)ah85&fK4T>6~1c*<8l40gq6)Op3gy(xt z3^t5~zB$nRjM=vswH>yM>fi9Iz7UN7oh%mg9tC~?jcEwzT;KFd4aDg!`Wh#x zuYzLIBGu!L!f%VKbX5lC)xJPx)jY&j7RA>e5SY2owRTREwX0v}WCXEDiHz9&njM6IjqWDuSeN_8of-6{(rAS!g3-q!+6Vg}LbZrL5k)ty6{TsCcC(wz%=Mhvy}Nfd zvpf6O;=>MX=A3iS?|1LH_f8mVJPiaI2s99AAW#DWP=jq%rlI+NT3{nJ&KNw64(`l4 z`GqmQ#9O>mv4M__N*v$N0tTm7_H&KJIOE-RNdkl4!No#z!=0bojoZm8DxenhD0xF? zXBp?EV*+qRWe3VFqO>!qva4zK#Wr)8dK8=2Ul z3RNw<;|yF+^emZF$vDqIebB>wKL6;Oss22dp=@Lpn?ilTJI;VmEcMp5m_vW?CA7a^ z_`tP3No!s#8%myJVm$LUZLA_2&T$6N#)5{S1)*PLQr*8&Eki5{-#<9JX#he>;#lCg{fOJSd#0Yjad8w>nk8Iu^t0!E{&ZCBaV z{b=*J!Jr2}nCNENhQFKehK*qHxAAH`Ecs-SMedF#5|fDPi->v|hox+7r7?hpv-Mh6 zATSZ>h1@rT&?;I$csg;nt{KPhhW|`4^yuL6tG>O{Be$#zhvAvaty=QhC&=#;vO2xL zborYP&JMM&$^Len#1YPwP;_Nd*Y)oZy+g&4H=QWTF*$i$-=J+K-@~yT$>Z9-fam5b zD!@}s3cJhWX=!))JKgjnnq)LaI{5omPBKgH)04>siXo3#7#awjjGw`zpOuyDXhi?# zuF+sm1i%pEgRjSr7zTS)@Y(l8L}_Ghtm}&cc}aFK8pkEePNC8sSy55g(YeE2xi2?M z0caFKqaB}dh~9ZD>Qk;N-zcCgD{lAYKzP@Noc!}|{Ttj)Z~lf2+ms6k@L6jh*cNb=+ich3z*k#l9@5|E!s4W5})e<&0sI#XnsZj ze)PKG;n@?=10rvRY{JMLuO8B4%a@8PF{c0x0jwydw=fAnV|4ekJqups{(a zeVC1DHZf=T5hp!{VZ=hwcuW#mNSC5^&mIo^A%xgia_7_kus%Y2FfrWAbAbKux0hlt=J%UBIPx(Hc3Q5RA>e5SYL=#RT%%idpFxO6AKNDDAp(!NqSf#tnm*~HlrZ*uqNx&E<{jo z5MX}po`%&{LHlN;4_lrm`>LVobJW=hteE$1Y&G0NZ2apm;H&_vRxN6OAa?{-X zd2;{}HU%D6H}8Lln4MzV*HxCD5N^QK!s$rmlkB)G6xEU(u$k2Dxrkz2>&~I z{RO0h83ari-p~%@a>b`+h&CFCFt)oyrK;A10T5Njw*!MmN~^_^*I>|&@QjitwQ&^{ zK}3094h-gsd&rV6u`m1LkBBLdxIaLO_TkUwk2jF{=*+&(0f1i;-Bf!t_;R2SOF%kgpW~sC4H@cFz;n%tG!UdY4_#8!0y!7)WK_r`2*C$s8_<7YrT~3 z!>Rx6)OncK^?-(PFkgO}a5Z-BLb$js?7NT#?Jfhmk{2=7bqJNbw^5K5-fc8fIQ7KZ zu4UsrJw3A;w7c~7rvAeCSiO?>JwQTu56GPNfLlkHzV8&$%B4E}>DhDB>A`IAG*V`S z4f?UaZ`(*C!#j4oG70+0dZpVhGULvR40QWNh8<3)W#|&f0c{1qAHwezbhnW3`)Hef zG0^-@Nu^R%^hfLU3;ia}$N`}J#|57N|8bq`^>p#-w#P&H;SDv558?|HQjLEVgGcHcKtq1S zq=*&X=}hWFR2Fsq;*7nmuXDf=0{F{LU$;mDo~Zn{*-i8IEsI~rvOOzG-V>!VWYsQY zvqgNcYFw5qGCxG1j^M1BKzr6S>CJb0U%lFxTgNa!$>oN-W|Vyv+?8S)GgmyY?wze$ z=Ug|2hRV-bR67Ia#f|_{WP0VJ#`5}q!Xbxl1Fb+`-}W(htpA92i%^#upFN$;me)H( zy)uV#!*A7C{RG+_@VDprXsf_$eSua$3)neb<53M#kKG0NIu4CvNVRU{*E08Es{Yxv=9vE1->}cWwU-*gtDz5V^h*j=j_fyv@)2aVx=Voq-+DLIdg4K1hD9 z`#y_8_&>p+_l-|}-)wWzz_%nA59P`!eCzxQk?(FQ$8?6o{AeJZ{JAMlgo#KFXuE}i zn3d{@1e0tNmM$n1a1LGetr*3tBWK6 O0000Px)ut`KgRCodHT7767MHHWz&4tv~&&HJ6iXVugt%7a9fVn_YfRY4zwur*LE zc=`8>+ffc+J*VVfdKOw8`~0s6fPsNeubodMALc|lEfP!$veoP`Vqcu%kFX6uclVLt zTp}?9g|Ar>cjeCSl7!ixwgFJ7_7)u2zshH4?Tr@OCqdjewt7Rg{G_xEfLGUgHaKhp zkd2X7={^8nojJGU_AS6IB)!VVwgph!NxiD9ncTJk!14Z!86&UKYy-d)_ADY3e|S}4 zqujOuh(_waSX)|p3t>t#fOs4EjF*>%?Yn?PFdTkJTEP3MOyqS~W2{1J{S00N!m5M~?UlvBRSkd_i6O zMj%7y^1}$uU~kAaH)Iu__VFa>+Qd0Qj=M(xLCP7>u%Y>6zNAA?_8kk9o@@*6n6e&`(Swq2 zV0AJiuS)=CcGIRcKj?@i6-NNTDV;a20r?J%i@WhSZt}imBt)4vszQB*2#xUgJb@3H zgzzV%V{MN#b}k!WATUPv;O`K*Pe)@Gz} z%IkGBL2k#`cA|-WI(n8$G}3TfQCJ;zmM_s|2H>5hj6BuevU7iyAv&@n3s4k3qN-$% zjw32ipeoig@;r(;y>@^9(VOCG;&tQr#X6;@P3a~?2?EH~CQX(kM;6e!tMO|f|BKmM z1QoA!^$fL|wMm-%9KN6?4`UZuZ`KF)BX@v;r@YKGmlR#SBhTSKoj0@gq4Z;g(F0_? zGA{dwU-^AP@EtfiysZCVn&trCGRKFhiN_1Cf z0zW4{>HMrtPqB)UCsKC>_q5Ex$rS(=L1?KT!OwX(vlDvc)JCKkL?uC5*>5==kQ0U&>k%o_qyoynG9e^dF`})Sp6JqueoQIm=`nKRQ zyOB^)hHdXMUV0AwKF5+7jz${sTwS5|B@C85^KpX92KfXZ0UrS$0UrS$0UrS$0UrS$ cfr23LHzAPa4>pm&-v9sr07*qoM6N<$f>I#Lq5uE@ literal 0 HcmV?d00001 diff --git a/ios/StatusIm/Images.xcassets/icon_public_group.imageset/icon_public_group.png b/ios/StatusIm/Images.xcassets/icon_public_group.imageset/icon_public_group.png new file mode 100644 index 0000000000000000000000000000000000000000..4a57d714eb4976ddd802c239f445fa66631cbac8 GIT binary patch literal 751 zcmVPx%sYygZR9Fe^Ry%AHK@goe+u>K3P(=}u!mmw{2nhrSxN+gQuqY7bES&Td&>&F& zQVK`~NQi<4+X@$pR3H*tn2I7o6#Oa*L?}QAQIMcW2s^$VX3svnc6|0B>k5QdTF>n4 z-h1z6_ht>yZ~uD+(C-9f%%v$Ly1_gvLC_MZRP3|Lsi^}$d=zw(2nM-NY>+tD$`Nc0 z^fJ!pOT!hbstXOu(`RB2B^CkfbTB#HgO2amo&=a?=|GjLIsxg-r2nc`_SwJ|Zm=D2 zNIF^10*FY<&KJgjm<&KiLcJm?L+!yS)IPpB>MB4I=FH;Z+S`$yH48_WJnTSl+;Mxd zt^#sq;Sr07|3T+d%;bxsA&aW=o=+yDUwF*}bsgV;YtD_xc2%8|zUv{h7Yg|5Jirf6 zIKFDp5?A@2|CGJI^f5cPIH}G_A2D#Af4&34tF6J%olWzt0d>5v@HG6hQvSvns9mk7 zU6@YAZaHgsTOveQ;sa`DQVVM1>16D+Gw;QA{Y#daD_jN;GYv3&h6pb>Bl~%85*)X) z$g!7cWAY#$R-W?SI&T5vjPBlcoxz_sAn7>2@kJ&-$*~$a?{f&@)Zdaz%&r0=kw|s> zz@8Ht;w%fX4`oA)++!?iTSDW85noZ`Uj43HpaSLdPe#gOBg)_V5Mkg$AYi>cdpiD3 hUDNmb8TjWi@EcVK@AE%$vf=;$002ovPDHLkV1kLjTLu6C literal 0 HcmV?d00001 diff --git a/ios/StatusIm/Images.xcassets/icon_public_group_big.imageset/Contents.json b/ios/StatusIm/Images.xcassets/icon_public_group_big.imageset/Contents.json new file mode 100644 index 0000000000..a6700a5eac --- /dev/null +++ b/ios/StatusIm/Images.xcassets/icon_public_group_big.imageset/Contents.json @@ -0,0 +1,23 @@ +{ + "images" : [ + { + "idiom" : "universal", + "filename" : "icon_public_group_big.png", + "scale" : "1x" + }, + { + "idiom" : "universal", + "filename" : "icon_public_group_big-1.png", + "scale" : "2x" + }, + { + "idiom" : "universal", + "filename" : "icon_public_group_big-2.png", + "scale" : "3x" + } + ], + "info" : { + "version" : 1, + "author" : "xcode" + } +} \ No newline at end of file diff --git a/ios/StatusIm/Images.xcassets/icon_public_group_big.imageset/icon_public_group_big-1.png b/ios/StatusIm/Images.xcassets/icon_public_group_big.imageset/icon_public_group_big-1.png new file mode 100644 index 0000000000000000000000000000000000000000..a73bc5942088faa2e50b75cfc1ad570558772ba7 GIT binary patch literal 2109 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 literal 0 HcmV?d00001 diff --git a/ios/StatusIm/Images.xcassets/icon_public_group_big.imageset/icon_public_group_big.png b/ios/StatusIm/Images.xcassets/icon_public_group_big.imageset/icon_public_group_big.png new file mode 100644 index 0000000000000000000000000000000000000000..2e9ffa2d52dce11786e32a4d51df9b9b4f6f0c33 GIT binary patch literal 1406 zcmV-^1%djBP)Px)I7vi7RA>e5SWRpjMHHS{JAXwSij=m=Zd?vM6_7#^5{?9-LLe0+q@sYhaKH|! zgi^<*5?qk*6{M2CMi3{l5ErCM2+E}gM1hMJR8fV$O981()=t}qLrI`X9PjWw+iTC- zYwtQFPK7*@JwNZwyzl+Y?7U&DRazEkS)gTsy|e(|E8(&8qHA?|`KVy5TQSWWYE=Cx z&biqro~9`)k|K9a^1zlp@>Cb` z=EKSqZ=rdT`fkNl0orW0GnuF1DhM%yiwnl1ShOI_ZFM{S4gg<9km#uOF0Q1eB0Vd_ z5}GiM!yuQ+?0HX?yLDPM6$s6*+{;!s-uWwIgkaMBUae}$;*4KMfa(Y*-SqiVfd_jQ z;>Y=xMVIS9ME!Pg+$aq})`3#TrQxW+(D==RVs+ypT>G#W;IQZhLg5N{QwRdx-_@B) zoa$b7kzFFw@fjLhD)kXZp7*As0)k~fC-CJJ?JWS#KnB1vUGcG$c1XPve~E9}xpt-( zo;03gCi{?9Q-m0vjrCoWSFTbZJdu7`nC4?L6XX0EEc}H63oD%KiP7Fg8+{i$A}40B zyhn9{EF#tLEHcHzZj|dhDf20bCP)wy|V4&koNBIdig+ce_K^2U3E5io%8~lrj)hd*~(!D;#6{hdR zWe&Gd+r>8->vP0b38=~g#K2kGNyfAJ>vZLWVjuStF^Fr&pvW<{lrc6!D#$Z z*O1|9xTcm?LW6`P1fcspttK&9360>mb}L-3m(aw8P>|5T6vcv9fMisw+MgC#u4^h_ zG1*c|VGh90k6W|`>rzTdiO)TXqSs0(vDa?SN3}y<)^}B)a*@hdB}-$|AFkx{(ueTh zk!xJXek&#Q`FWgumW=kj;AIU@ZmPG?d`!Ea`8!o?oIyN?yiX@pA;qjWt3ZP%jsW~q z=;a>?XcTj^*qHAYINbjoH?jLPJ4f<#cLpP$7JuyYr0DoNmp+C*PBL-U&RxI91s_es zwD0S4m8lJT02W>=PiJg+W~E2&Q+q1HH}FKL`}cKxBGdAo;mRbub(t(J)6k})`PD{V zL@k$>~R<8{TPzdsD%n1F*^OM ze|kjw(;A~XJa_v(wzm2sV!WKk!upm1GVgzBH|znQ-#2Gwa}jtVAASUIeTy#)jiujI z_O*XQV94@fZS_4FJWeaTZ~5kkzLTZlW0Zu4$Csw?aT{q6$TY48jm~iu(eNgw75jR% zGYFlpTvsnK@Jj(zd!y9d!N#@}pjSA&6`jCIa*jfy7M>z)I-sg2cI)MCTOlL^e(l`y z1G%l-5YGE&060K2I;n7;f2p+jW@krwewF!K?Un^v7HC=E|7C%H0rS<=sAWC@GXMYp M07*qoM6N<$f*p{biU0rr literal 0 HcmV?d00001 diff --git a/src/status_im/android/core.cljs b/src/status_im/android/core.cljs index 14a6ef994c..d5876e0bca 100644 --- a/src/status_im/android/core.cljs +++ b/src/status_im/android/core.cljs @@ -23,7 +23,8 @@ [status-im.accounts.screen :refer [accounts]] [status-im.transactions.screen :refer [confirm]] [status-im.chats-list.screen :refer [chats-list]] - [status-im.new-group.screen :refer [new-group]] + [status-im.new-group.screen-private :refer [new-group]] + [status-im.new-group.screen-public :refer [new-public-group]] [status-im.participants.views.add :refer [new-participants]] [status-im.participants.views.remove :refer [remove-participants]] [status-im.group-settings.screen :refer [group-settings]] @@ -98,6 +99,7 @@ :remove-participants remove-participants :chat-list main-tabs :new-group new-group + :new-public-group new-public-group :group-settings group-settings :contact-list main-tabs :contact-list-search-results contacts-search-results diff --git a/src/status_im/android/platform.cljs b/src/status_im/android/platform.cljs index b88b388176..7d565ad2d1 100644 --- a/src/status_im/android/platform.cljs +++ b/src/status_im/android/platform.cljs @@ -20,7 +20,7 @@ :additional-height 0} :chat {:new-message {:border-top-color styles/color-transparent :border-top-width 0.5}} - :discover {:subtitle {:color styles/color-gray2 + :discover {:subtitle {:color styles/color-gray2 :font-size 14} :popular {:border-radius 1 :margin-top 2 @@ -72,14 +72,17 @@ ;; Structure to be exported (def platform-specific - {:component-styles component-styles - :fonts fonts - :list-selection-fn show-dialog - :tabs {:tab-shadows? true} - :chats {:action-button? true - :new-chat-in-toolbar? false} - :contacts {:action-button? true - :new-contact-in-toolbar? false - :uppercase-subtitles? false - :group-block-shadows? true} - :discover {:uppercase-subtitles? false}}) + {:component-styles component-styles + :fonts fonts + :list-selection-fn show-dialog + :tabs {:tab-shadows? true} + :chats {:action-button? true + :new-chat-in-toolbar? false} + :contacts {:action-button? true + :new-contact-in-toolbar? false + :uppercase-subtitles? false + :group-block-shadows? true} + :discover {:uppercase-subtitles? false} + :public-group-icon-container {:margin-top 4} + :private-group-icon-container {:margin-top 6} + :public-group-chat-hash-style {:top 10 :left 4}}) diff --git a/src/status_im/chat/handlers.cljs b/src/status_im/chat/handlers.cljs index 45501da487..04a3e7542b 100644 --- a/src/status_im/chat/handlers.cljs +++ b/src/status_im/chat/handlers.cljs @@ -511,17 +511,18 @@ (after (fn [_ _] (dispatch [:navigation-replace :chat-list]))) (u/side-effect! (fn [{:keys [web3 current-chat-id chats current-public-key]} _] - (let [{:keys [public-key private-key]} (chats current-chat-id)] + (let [{:keys [public-key private-key public?]} (chats current-chat-id)] (protocol/stop-watching-group! {:web3 web3 :group-id current-chat-id}) - (protocol/leave-group-chat! - {:web3 web3 - :group-id current-chat-id - :keypair {:public public-key - :private private-key} - :message {:from current-public-key - :message-id (random/id)}})) + (when-not public? + (protocol/leave-group-chat! + {:web3 web3 + :group-id current-chat-id + :keypair {:public public-key + :private private-key} + :message {:from current-public-key + :message-id (random/id)}}))) (dispatch [:remove-chat current-chat-id])))) (register-handler :remove-chat @@ -563,12 +564,13 @@ [{:keys [web3 current-public-key chats]} [_ {:keys [from chat-id message-id]}]] (when-not (console? chat-id) - (let [{:keys [group-chat]} (chats chat-id)] - (protocol/send-seen! {:web3 web3 - :message {:from current-public-key - :to from - :group-id (when group-chat chat-id) - :message-id message-id}})))) + (let [{:keys [group-chat public?]} (chats chat-id)] + (when-not public? + (protocol/send-seen! {:web3 web3 + :message {:from current-public-key + :to from + :group-id (when group-chat chat-id) + :message-id message-id}}))))) (register-handler :send-seen! [(after (fn [_ [_ {:keys [message-id]}]] (messages/update {:message-id message-id @@ -579,7 +581,7 @@ (defn send-clock-value-request! [{:keys [web3 current-public-key]} [_ {:keys [message-id from]}]] - (protocol/send-clock-value-request! {:web3 web3 + (protocol/send-clock-value-request! {:web3 web3 :message {:from current-public-key :to from :message-id message-id}})) @@ -605,9 +607,9 @@ (register-handler :send-clock-value! (u/side-effect! - (fn [db [_ to message-id]] - (let [{:keys [clock-value]} (messages/get-by-id message-id)] - (send-clock-value! db to message-id clock-value))))) + (fn [db [_ to message-id]] + (let [{:keys [clock-value]} (messages/get-by-id message-id)] + (send-clock-value! db to message-id clock-value))))) (register-handler :set-web-view-url (fn [{:keys [current-chat-id] :as db} [_ url]] @@ -663,7 +665,7 @@ (register-handler :update-message-overhead! (u/side-effect! - (fn [_ [_ chat-id network-status]] - (if (= network-status :offline) - (chats/inc-message-overhead chat-id) - (chats/reset-message-overhead chat-id))))) + (fn [_ [_ chat-id network-status]] + (if (= network-status :offline) + (chats/inc-message-overhead chat-id) + (chats/reset-message-overhead chat-id))))) diff --git a/src/status_im/chat/handlers/send_message.cljs b/src/status_im/chat/handlers/send_message.cljs index 6861fbfda2..7599620e66 100644 --- a/src/status_im/chat/handlers/send_message.cljs +++ b/src/status_im/chat/handlers/send_message.cljs @@ -25,23 +25,23 @@ to-message handler-data content-type]}] (let [content (or request {:command (command :name) :params params})] - {:message-id id - :from identity - :to chat-id - :timestamp (time/now-ms) - :content (assoc content :handler-data handler-data - :type (name (:type command)) - :content-command (:name command)) - :content-type (or content-type - (if request - content-type-command-request - content-type-command)) - :outgoing true - :to-message to-message - :type (:type command) - :has-handler (:has-handler command) - :clock-value (inc clock-value) - :show? true})) + {:message-id id + :from identity + :to chat-id + :timestamp (time/now-ms) + :content (assoc content :handler-data handler-data + :type (name (:type command)) + :content-command (:name command)) + :content-type (or content-type + (if request + content-type-command-request + content-type-command)) + :outgoing true + :to-message to-message + :type (:type command) + :has-handler (:has-handler command) + :clock-value (inc clock-value) + :show? true})) (register-handler :send-chat-message (u/side-effect! @@ -173,7 +173,7 @@ (register-handler ::prepare-message (u/side-effect! (fn [{:keys [network-status] :as db} [_ {:keys [chat-id identity message] :as params}]] - (let [{:keys [group-chat]} (get-in db [:chats chat-id]) + (let [{:keys [group-chat public?]} (get-in db [:chats chat-id]) clock-value (messages/get-last-clock-value chat-id) message' (cu/check-author-direction db chat-id @@ -186,9 +186,13 @@ :timestamp (time/now-ms) :clock-value (inc clock-value) :show? true}) - message'' (if group-chat - (assoc message' :group-id chat-id :message-type :group-user-message) - (assoc message' :to chat-id :message-type :user-message)) + message'' (cond-> message' + (and group-chat public?) + (assoc :group-id chat-id :message-type :public-group-user-message) + (and group-chat (not public?)) + (assoc :group-id chat-id :message-type :group-user-message) + (not group-chat) + (assoc :to chat-id :message-type :user-message)) params' (assoc params :message message'')] (dispatch [:update-message-overhead! chat-id network-status]) (dispatch [:set-chat-ui-props :sending-disabled? false]) @@ -258,7 +262,7 @@ (register-handler ::send-message! (u/side-effect! - (fn [{:keys [web3 chats network-status] + (fn [{:keys [web3 chats network-status current-account-id accounts] :as db} [_ {{:keys [message-type] :as message} :message chat-id :chat-id}]] @@ -274,23 +278,33 @@ payload) options {:web3 web3 :message (assoc message' :payload payload)}] - (if (= message-type :group-user-message) + (cond + (= message-type :group-user-message) (let [{:keys [public-key private-key]} (chats chat-id)] (protocol/send-group-message! (assoc options :group-id chat-id :keypair {:public public-key :private private-key}))) + + (= message-type :public-group-user-message) + (protocol/send-public-group-message! + (let [username (get-in accounts [current-account-id :name])] + (assoc options :group-id chat-id + :username username))) + + :else (protocol/send-message! (assoc-in options [:message :to] (:to message))))))))))) (register-handler ::send-command-protocol! (u/side-effect! - (fn [{:keys [web3 current-public-key chats network-status] :as db} - [_ {:keys [chat-id command command-message]}]] + (fn [{:keys [web3 current-public-key chats network-status + current-account-id accounts] :as db} + [_ {:keys [chat-id command]}]] (log/debug "sending command: " command) (when (cu/not-console? chat-id) (let [{:keys [public-key private-key]} (chats chat-id) - {:keys [group-chat]} (get-in db [:chats chat-id]) + {:keys [group-chat public?]} (get-in db [:chats chat-id]) payload (-> command (select-keys [:content :content-type @@ -303,10 +317,19 @@ :message {:from current-public-key :message-id (:message-id command) :payload payload}}] - (if group-chat + (cond + (and group-chat (not public?)) (protocol/send-group-message! (assoc options :group-id chat-id :keypair {:public public-key :private private-key})) + + (and group-chat public?) + (protocol/send-public-group-message! + (let [username (get-in accounts [current-account-id :name])] + (assoc options :group-id chat-id + :username username))) + + :else (protocol/send-message! (assoc-in options [:message :to] chat-id)))))))) diff --git a/src/status_im/chat/styles/message.cljs b/src/status_im/chat/styles/message.cljs index 21ab45c1d4..e45e0d223e 100644 --- a/src/status_im/chat/styles/message.cljs +++ b/src/status_im/chat/styles/message.cljs @@ -4,7 +4,8 @@ color-blue selected-message-color text1-color - text2-color]] + text2-color + color-gray]] [status-im.constants :refer [text-content-type content-type-command]])) @@ -125,6 +126,9 @@ (when selected {:backgroundColor selected-message-color})))) +(def author + {:color color-gray}) + (def comand-request-view {:paddingRight 16}) diff --git a/src/status_im/chat/styles/screen.cljs b/src/status_im/chat/styles/screen.cljs index a65f73f385..aa7a6229c5 100644 --- a/src/status_im/chat/styles/screen.cljs +++ b/src/status_im/chat/styles/screen.cljs @@ -54,9 +54,10 @@ :fontSize 16}) (def group-icon - {:marginTop 4 - :width 14 - :height 9}) + {:margin-top 4 + :margin-bottom 2.7 + :width 14 + :height 9}) (def up-icon {:width 14 diff --git a/src/status_im/chat/views/actions.cljs b/src/status_im/chat/views/actions.cljs index a7907a68ca..ca6b7218bd 100644 --- a/src/status_im/chat/views/actions.cljs +++ b/src/status_im/chat/views/actions.cljs @@ -70,11 +70,11 @@ :height 13} :handler #(dispatch [:show-group-settings])}) -(defn group-chat-items [members] - [(item-members members) - item-search - item-notifications - item-settings]) +(defn group-chat-items [members public?] + (into (if public? [] [(item-members members)]) + [item-search + item-notifications + item-settings])) (defn user-chat-items [chat-id] [(item-user chat-id) @@ -114,21 +114,22 @@ subtitle])]]]) (defn actions-list-view [] - (let [{:keys [group-chat chat-id]} - (subscribe [:chat-properties [:group-chat :chat-id]]) + (let [{:keys [group-chat chat-id public?]} + (subscribe [:chat-properties [:group-chat :chat-id :public?]]) members (subscribe [:current-chat-contacts]) status-bar-height (get-in platform-specific [:component-styles :status-bar :default :height])] - (when-let [actions (if @group-chat - (group-chat-items @members) - (user-chat-items @chat-id))] - [view (merge - (st/actions-wrapper status-bar-height) - (get-in platform-specific [:component-styles :actions-list-view])) - [view st/actions-separator] - [view st/actions-view - (for [action actions] - (if action - ^{:key action} [action-view action]))]]))) + (fn [] + (when-let [actions (if @group-chat + (group-chat-items @members @public?) + (user-chat-items @chat-id))] + [view (merge + (st/actions-wrapper status-bar-height) + (get-in platform-specific [:component-styles :actions-list-view])) + [view st/actions-separator] + [view st/actions-view + (for [action actions] + (if action + ^{:key action} [action-view action]))]])))) (defn actions-view [] [overlay {:on-click-outside #(dispatch [:set-chat-ui-props :show-actions? false])} diff --git a/src/status_im/chat/views/message.cljs b/src/status_im/chat/views/message.cljs index a1b1503748..22d73c2334 100644 --- a/src/status_im/chat/views/message.cljs +++ b/src/status_im/chat/views/message.cljs @@ -46,10 +46,10 @@ members (subscribe [:current-chat-contacts])] (fn [{:keys [messages-count content datemark]}] (let [{:keys [status]} (if @group-chat - {:photo-path nil - :status nil - :last-online 0} - (first @members))] + {:photo-path nil + :status nil + :last-online 0} + (first @members))] [view st/status-container [chat-icon-message-status @chat-id @group-chat @name @color false] [text {:style st/status-from @@ -143,11 +143,10 @@ :current-chat-id current-chat-id}]])) (defn message-view - [message content] + [{:keys [username same-author index] :as message} content] [view (st/message-view message) - #_(when incoming-group - [text {:style message-author-text} - "Justas"]) + (when (and username (or (= 1 index) (not same-author))) + [text {:style st/author} username]) content]) (defmulti message-content (fn [_ message _] @@ -202,7 +201,7 @@ (defn text-message [{:keys [content] :as message}] [message-view message - (let [parsed-text (parse-text content) + (let [parsed-text (parse-text content) simple-text? (= (count parsed-text) 2)] (if simple-text? [autolink {:style (st/text-message message) @@ -374,10 +373,10 @@ children)])})) (into [view] children))) -(defn chat-message [{:keys [outgoing message-id chat-id user-statuses from content] :as message}] - (let [my-identity (subscribe [:get :current-public-key]) - status (subscribe [:get-in [:message-data :user-statuses message-id my-identity]]) - preview (subscribe [:get-in [:message-data :preview message-id]])] +(defn chat-message [{:keys [outgoing message-id chat-id user-statuses from] :as message}] + (let [my-identity (subscribe [:get :current-public-key]) + status (subscribe [:get-in [:message-data :user-statuses message-id my-identity]]) + preview (subscribe [:get-in [:message-data :preview message-id]])] (r/create-class {:component-will-mount (fn [] diff --git a/src/status_im/chat/views/toolbar_content.cljs b/src/status_im/chat/views/toolbar_content.cljs index 312d67ec0e..9e333c6784 100644 --- a/src/status_im/chat/views/toolbar_content.cljs +++ b/src/status_im/chat/views/toolbar_content.cljs @@ -49,22 +49,31 @@ :synced (label :t/sync-synced) online-text)}]) -(defn group-last-activity [{:keys [contacts sync-state]}] +(defn group-last-activity [{:keys [contacts sync-state public?]}] (if (or (= sync-state :in-progress) (= sync-state :synced)) [last-activity {:sync-state sync-state}] - [view {:flex-direction :row} - [icon :group st/group-icon] - [text {:style st/members - :font :medium} - (let [cnt (inc (count contacts))] - (label-pluralize cnt :t/members-active))]])) + (if public? + [view {:flex-direction :row} + [text {:font :default + :style (get-in platform-specific [:component-styles :toolbar-last-activity])} + (label :t/public-group-status)]] + [view {:flex-direction :row} + [icon :group st/group-icon] + [text {:style st/members + :font :medium} + (if public? + (label :t/public-group-status) + (let [cnt (inc (count contacts))] + (label-pluralize cnt :t/members-active)))]]))) (defn toolbar-content-view [] (let [{:keys [group-chat name contacts - chat-id]} (subscribe [:chat-properties [:group-chat :name :contacts :chat-id]]) + chat-id + public?]} + (subscribe [:chat-properties [:group-chat :name :contacts :chat-id :public?]]) show-actions? (subscribe [:chat-ui-props :show-actions?]) accounts (subscribe [:get :accounts]) contact (subscribe [:get-in [:contacts @chat-id]]) @@ -72,15 +81,19 @@ (fn [] [view (st/chat-name-view (or (empty? @accounts) @show-actions?)) - [text {:style st/chat-name-text - :number-of-lines 1 - :font :toolbar-title} - (if (str/blank? @name) - (generate-gfy) - (or (get-contact-translated @chat-id :name @name) - (label :t/chat-name)))] + (let [chat-name (if (str/blank? @name) + (generate-gfy) + (or (get-contact-translated @chat-id :name @name) + (label :t/chat-name)))] + [text {:style st/chat-name-text + :number-of-lines 1 + :font :toolbar-title} + (if @public? + (str "#" chat-name) + chat-name)]) (if @group-chat [group-last-activity {:contacts @contacts + :public? @public? :sync-state @sync-state}] [last-activity {:online-text (online-text @contact @chat-id) :sync-state @sync-state}])]))) diff --git a/src/status_im/chats_list/screen.cljs b/src/status_im/chats_list/screen.cljs index e9299406cb..35bb1e1b0a 100644 --- a/src/status_im/chats_list/screen.cljs +++ b/src/status_im/chats_list/screen.cljs @@ -6,6 +6,7 @@ view animated-view text + icon image touchable-highlight]] [status-im.components.action-button :refer [action-button @@ -55,8 +56,12 @@ {:title (label :t/new-group-chat) :buttonColor :#1abc9c :onPress #(dispatch [:navigate-to :new-group])} - [ion-icon {:name :md-person - :style st/person-stalker-icon}]]]) + [icon :private_group_big st/group-icon]] + [action-button-item + {:title (label :t/new-public-group-chat) + :buttonColor :#1abc9c + :onPress #(dispatch [:navigate-to :new-public-group])} + [icon :public_group_big st/group-icon]]]) (defn chat-shadow-item [] [view {:height 3} diff --git a/src/status_im/chats_list/styles.cljs b/src/status_im/chats_list/styles.cljs index 8dfe379c2a..a63b77e2e3 100644 --- a/src/status_im/chats_list/styles.cljs +++ b/src/status_im/chats_list/styles.cljs @@ -32,9 +32,9 @@ :border-bottom-color color-separator}) (def chat-container - {:flex-direction :row - :background-color color-white - :height 94}) + {:flex-direction :row + :background-color color-white + :height 94}) (def chat-icon-container {:margin-top -2 @@ -44,24 +44,41 @@ :height 48}) (def item-container - {:flex-direction :column - :margin-left 30 - :padding-top 16 - :padding-right 16 - :flex 1}) + {:flex-direction :column + :margin-left 30 + :padding-top 16 + :padding-right 16 + :flex 1}) (def name-view {:flex-direction :row}) (def name-text - {:color text1-color - :font-size 14}) + {:color text1-color + :font-size 14}) -(def group-icon - {:margin-top 5 - :margin-left 8 - :width 14 - :height 9}) +(def private-group-icon-container + {:width 16 + :height 9 + :padding-top -4 + :margin-top (get-in p/platform-specific [:private-group-icon-container :margin-top]) + :margin-right 6}) + +(def private-group-icon + {:width 16 + :height 16}) + +(def public-group-icon-container + {:width 16 + :height 12 + :padding-top -2 + :margin-top (get-in p/platform-specific [:public-group-icon-container :margin-top]) + :margin-right 6}) + +(def public-group-icon + {:width 16 + :height 16 + :margin-bottom -20}) (def memebers-text {:marginTop 2 @@ -124,7 +141,7 @@ :height 22 :color color-white}) -(def person-stalker-icon - {:fontSize 20 - :height 22 - :color color-white}) +(def group-icon + {:height 22 + :width 22 + :tint-color :white}) diff --git a/src/status_im/chats_list/views/inner_item.cljs b/src/status_im/chats_list/views/inner_item.cljs index d3c8d373d4..545f3893f9 100644 --- a/src/status_im/chats_list/views/inner_item.cljs +++ b/src/status_im/chats_list/views/inner_item.cljs @@ -77,24 +77,34 @@ unviewed-messages]])) (defn chat-list-item-inner-view [{:keys [chat-id name color last-message - online group-chat contacts] :as chat}] + online group-chat contacts public?] + :as chat}] (let [last-message (or (first (sort-by :clock-value > (:messages chat))) last-message) name (or (get-contact-translated chat-id :name name) - (generate-gfy))] + (generate-gfy)) + private-group? (and group-chat (not public?)) + public-group? (and group-chat public?)] [view st/chat-container [view st/chat-icon-container [chat-icon-view-chat-list chat-id group-chat name color online]] [view st/item-container [view st/name-view - [text {:style st/name-text - :font :medium} - (if (str/blank? name) - (generate-gfy) - (truncate-str name 30))] - (when group-chat - [icon :group st/group-icon]) - (when group-chat + (when public-group? + [view st/public-group-icon-container + [icon :public_group st/public-group-icon]]) + (when private-group? + [view st/private-group-icon-container + [icon :private_group st/private-group-icon]]) + (let [chat-name (if (str/blank? name) + (generate-gfy) + (truncate-str name 30))] + [text {:style st/name-text + :font :medium} + (if public-group? + (str "#" chat-name) + chat-name)]) + #_(when private-group? [text {:style st/memebers-text} (label-pluralize (inc (count contacts)) :t/members)])] [message-content-text last-message]] diff --git a/src/status_im/components/text_field/view.cljs b/src/status_im/components/text_field/view.cljs index 7ad2ac9c16..6fcab178ab 100644 --- a/src/status_im/components/text_field/view.cljs +++ b/src/status_im/components/text_field/view.cljs @@ -34,11 +34,12 @@ :on-focus #() :on-blur #() :on-change-text #() - :on-change #()}) + :on-change #() + :auto-capitalize :sentences}) (defn field-animation [{:keys [top to-top font-size to-font-size line-width to-line-width]}] - (let [duration (:label-animation-duration config) + (let [duration (:label-animation-duration config) animation (anim/parallel [(anim/timing top {:toValue to-top :duration duration}) (anim/timing font-size {:toValue to-font-size @@ -101,10 +102,14 @@ label-font-size line-width current-value - max-line-width]} (r/state component) + max-line-width + valid-value + temp-value + max-length]} (r/state component) {:keys [wrapper-style input-style label-hidden? line-color focus-line-color secure-text-entry - label-color error-color error label value on-focus on-blur - on-change-text on-change on-end-editing editable placeholder]} (merge default-props (r/props component)) + label-color error-color error label value on-focus on-blur validator auto-focus + on-change-text on-change on-end-editing editable placeholder auto-capitalize]} + (merge default-props (r/props component)) line-color (if error error-color line-color) focus-line-color (if error error-color focus-line-color) label-color (if (and error (not float-label?)) error-color label-color) @@ -118,6 +123,7 @@ :placeholder (or placeholder "") :editable editable :secure-text-entry secure-text-entry + :auto-capitalize auto-capitalize :on-focus #(on-input-focus {:component component :animation {:top label-top :to-top (:label-top config) @@ -137,21 +143,34 @@ :onBlur on-blur}) :on-change-text (fn [text] (r/set-state component {:current-value text}) - (on-change-text text)) + (if (or (not validator) (validator text)) + (do + (r/set-state component {:valid-value text + :temp-value nil}) + (on-change-text text)) + (r/set-state component {:temp-value valid-value + :max-length (count valid-value)}))) :on-change #(on-change %) :default-value value + :value temp-value + :max-length max-length :on-submit-editing #(.blur @input-ref) - :on-end-editing (when on-end-editing - on-end-editing)}] + :on-end-editing (when on-end-editing on-end-editing) + :auto-focus (true? auto-focus)}] [view {:style (st/underline-container line-color) :onLayout #(r/set-state component {:max-line-width (get-width %)})} [animated-view {:style (st/underline focus-line-color line-width)}]] [text {:style (st/error-text error-color)} error]])) (defn text-field [_ _] - (let [component-data {:get-initial-state get-initial-state - :component-will-mount component-will-mount - :display-name "text-field" - :reagent-render reagent-render}] + (let [component-data {:get-initial-state get-initial-state + :component-will-mount component-will-mount + :display-name "text-field" + :reagent-render reagent-render + :component-did-update (fn [comp] + (let [{:keys [temp-value]} (r/state comp)] + (when temp-value + (r/set-state comp {:temp-value nil + :max-length nil}))))}] ;(log/debug "Creating text-field component: " data) (r/create-class component-data))) diff --git a/src/status_im/contacts/styles.cljs b/src/status_im/contacts/styles.cljs index 25a9592d31..c19c8440ed 100644 --- a/src/status_im/contacts/styles.cljs +++ b/src/status_im/contacts/styles.cljs @@ -132,6 +132,10 @@ :top 16 :left 13}) +(def group-icon + (assoc option-inner-image + :tint-color color-gray)) + (def spacing-top {:background-color color-white :height 8}) diff --git a/src/status_im/contacts/views/contact_list.cljs b/src/status_im/contacts/views/contact_list.cljs index 2af30c7069..4260f25daa 100644 --- a/src/status_im/contacts/views/contact_list.cljs +++ b/src/status_im/contacts/views/contact_list.cljs @@ -21,24 +21,35 @@ [status-im.contacts.views.contact-inner :refer [contact-inner-view]])) (defn new-group-chat-view [] - [touchable-highlight - {:on-press #(dispatch [:navigate-to :new-group])} - [view st/contact-container - [view st/option-inner-container - [view st/option-inner - [image {:source {:uri :icon_menu_group} - :style st/option-inner-image}]] - [view st/info-container - [text {:style st/name-text} - (label :t/new-group-chat)]]]]]) + [view + [touchable-highlight + {:on-press #(dispatch [:navigate-to :new-group])} + [view st/contact-container + [view st/option-inner-container + [view st/option-inner + [image {:source {:uri :icon_private_group_big} + :style st/group-icon}]] + [view st/info-container + [text {:style st/name-text} + (label :t/new-group-chat)]]]]] + [touchable-highlight + {:on-press #(dispatch [:navigate-to :new-public-group])} + [view st/contact-container + [view st/option-inner-container + [view st/option-inner + [image {:source {:uri :icon_public_group_big} + :style st/group-icon}]] + [view st/info-container + [text {:style st/name-text} + (label :t/new-public-group-chat)]]]]]]) (defn render-row [chat-modal click-handler action params] (fn [row _ _] (list-item - [contact-view {:contact row - :letter? chat-modal - :on-click (if click-handler - #(click-handler row action params))}]))) + [contact-view {:contact row + :letter? chat-modal + :on-click (when click-handler + #(click-handler row action params))}]))) (defn contact-list-entry [{:keys [click-handler icon icon-style label]}] [touchable-highlight diff --git a/src/status_im/data_store/realm/chats.cljs b/src/status_im/data_store/realm/chats.cljs index 66d12ecf52..822e572ce1 100644 --- a/src/status_im/data_store/realm/chats.cljs +++ b/src/status_im/data_store/realm/chats.cljs @@ -29,12 +29,19 @@ (defn get-active-group-chats [] (map - (fn [{:keys [chat-id public-key private-key]}] - {:chat-id chat-id - :keypair {:private private-key - :public public-key}}) + (fn [{:keys [chat-id public-key private-key public?]}] + (let [group {:group-id chat-id + :public? public?}] + (if (and public-key private-key) + (assoc group :keypair {:private private-key + :public public-key}) + group))) (realm/realm-collection->list (groups true)))) +(defn- get-by-id-obj + [chat-id] + (realm/get-one-by-field @realm/account-realm :chat :chat-id chat-id)) + (defn get-by-id [chat-id] (-> @realm/account-realm @@ -56,12 +63,12 @@ (defn set-inactive [chat-id] - (when-let [chat (get-by-id chat-id)] + (when-let [chat (get-by-id-obj chat-id)] (realm/write @realm/account-realm (fn [] (doto chat (aset "is-active" false) - (aset "removed-at" timestamp)))))) + (aset "removed-at" (timestamp))))))) (defn get-contacts [chat-id] @@ -72,8 +79,8 @@ (defn has-contact? [chat-id identity] (let [contacts (get-contacts chat-id) - contact (.find contacts (fn [object _ _] - (= identity (aget object "identity"))))] + contact (.find contacts (fn [object _ _] + (= identity (aget object "identity"))))] (if contact true false))) (defn- save-contacts @@ -97,9 +104,9 @@ (defn- delete-contacts [identities contacts] (doseq [contact-identity identities] - (when-let [contact (.find contacts (fn [object _ _] - (= contact-identity (aget object "identity"))))] - (realm/delete @realm/account-realm contact)))) + (when-let [contact (.find contacts (fn [object _ _] + (= contact-identity (aget object "identity"))))] + (realm/delete @realm/account-realm contact)))) (defn remove-contacts [chat-id identities] diff --git a/src/status_im/data_store/realm/schemas/account/core.cljs b/src/status_im/data_store/realm/schemas/account/core.cljs index 66f4e50faa..85a9629e22 100644 --- a/src/status_im/data_store/realm/schemas/account/core.cljs +++ b/src/status_im/data_store/realm/schemas/account/core.cljs @@ -1,7 +1,9 @@ (ns status-im.data-store.realm.schemas.account.core (:require [status-im.data-store.realm.schemas.account.v1.core :as v1] [status-im.data-store.realm.schemas.account.v2.core :as v2] - [status-im.data-store.realm.schemas.account.v3.core :as v3])) + [status-im.data-store.realm.schemas.account.v3.core :as v3] + [status-im.data-store.realm.schemas.account.v4.core :as v4] + )) ; put schemas ordered by version (def schemas [{:schema v1/schema @@ -12,4 +14,7 @@ :migration v2/migration} {:schema v3/schema :schemaVersion 3 - :migration v3/migration}]) + :migration v3/migration} + {:schema v4/schema + :schemaVersion 4 + :migration v4/migration}]) diff --git a/src/status_im/data_store/realm/schemas/account/v4/chat.cljs b/src/status_im/data_store/realm/schemas/account/v4/chat.cljs new file mode 100644 index 0000000000..d5cbf88ce4 --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v4/chat.cljs @@ -0,0 +1,42 @@ +(ns status-im.data-store.realm.schemas.account.v4.chat + (:require [taoensso.timbre :as log] + [status-im.components.styles :refer [default-chat-color]])) + +(def schema {:name :chat + :primaryKey :chat-id + :properties {:chat-id :string + :name :string + :color {:type :string + :default default-chat-color} + :group-chat {:type :bool + :indexed true} + :group-admin {:type :string + :optional true} + :is-active :bool + :timestamp :int + :contacts {:type :list + :objectType :chat-contact} + :removed-at {:type :int + :optional true} + :removed-from-at {:type :int + :optional true} + :added-to-at {:type :int + :optional true} + :updated-at {:type :int + :optional true} + :last-message-id :string + :message-overhead {:type :int + :default 0} + :public-key {:type :string + :optional true} + :private-key {:type :string + :optional true} + :contact-info {:type :string + :optional true} + :debug? {:type :bool + :default false} + :public? {:type :bool + :default false}}}) + +(defn migration [old-realm new-realm] + (log/debug "migrating chat schema v4")) diff --git a/src/status_im/data_store/realm/schemas/account/v4/core.cljs b/src/status_im/data_store/realm/schemas/account/v4/core.cljs new file mode 100644 index 0000000000..b4cfd1e1b8 --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v4/core.cljs @@ -0,0 +1,32 @@ +(ns status-im.data-store.realm.schemas.account.v4.core + (:require [status-im.data-store.realm.schemas.account.v4.chat :as chat] + [status-im.data-store.realm.schemas.account.v1.chat-contact :as chat-contact] + [status-im.data-store.realm.schemas.account.v1.command :as command] + [status-im.data-store.realm.schemas.account.v3.contact :as contact] + [status-im.data-store.realm.schemas.account.v1.discover :as discover] + [status-im.data-store.realm.schemas.account.v1.kv-store :as kv-store] + [status-im.data-store.realm.schemas.account.v4.message :as message] + [status-im.data-store.realm.schemas.account.v1.pending-message :as pending-message] + [status-im.data-store.realm.schemas.account.v1.processed-message :as processed-message] + [status-im.data-store.realm.schemas.account.v1.request :as request] + [status-im.data-store.realm.schemas.account.v1.tag :as tag] + [status-im.data-store.realm.schemas.account.v1.user-status :as user-status] + [taoensso.timbre :as log])) + +(def schema [chat/schema + chat-contact/schema + command/schema + contact/schema + discover/schema + kv-store/schema + message/schema + pending-message/schema + processed-message/schema + request/schema + tag/schema + user-status/schema]) + +(defn migration [old-realm new-realm] + (log/debug "migrating v4 account database: " old-realm new-realm) + (chat/migration old-realm new-realm) + (contact/migration old-realm new-realm)) diff --git a/src/status_im/data_store/realm/schemas/account/v4/message.cljs b/src/status_im/data_store/realm/schemas/account/v4/message.cljs new file mode 100644 index 0000000000..a5c11c3e4d --- /dev/null +++ b/src/status_im/data_store/realm/schemas/account/v4/message.cljs @@ -0,0 +1,38 @@ +(ns status-im.data-store.realm.schemas.account.v4.message + (:require [taoensso.timbre :as log])) + +(def schema {:name :message + :primaryKey :message-id + :properties {:message-id :string + :from :string + :to {:type :string + :optional true} + :group-id {:type :string + :optional true} + :content :string ;; TODO make it ArrayBuffer + :content-type :string + :username {:type :string + :optional true} + :timestamp :int + :chat-id {:type :string + :indexed true} + :outgoing :bool + :retry-count {:type :int + :default 0} + :same-author :bool + :same-direction :bool + :preview {:type :string + :optional true} + :message-type {:type :string + :optional true} + :message-status {:type :string + :optional true} + :user-statuses {:type :list + :objectType "user-status"} + :clock-value {:type :int + :default 0} + :show? {:type :bool + :default true}}}) + +(defn migration [_ _] + (log/debug "migrating message schema")) diff --git a/src/status_im/group_settings/screen.cljs b/src/status_im/group_settings/screen.cljs index ae733b9642..0bb40c0c44 100644 --- a/src/status_im/group_settings/screen.cljs +++ b/src/status_im/group_settings/screen.cljs @@ -160,11 +160,12 @@ (label :t/add-members)]]] [chat-members]])) -(defn group-settings [] +(defview group-settings [] + [public? [:chat :public?]] [view st/group-settings [new-group-toolbar] [scroll-view st/body - [chat-name] + (when-not public? [chat-name]) [members] [text {:style st/settings-text} (label :t/settings)] diff --git a/src/status_im/ios/core.cljs b/src/status_im/ios/core.cljs index 3860bbd02e..8734c9b925 100644 --- a/src/status_im/ios/core.cljs +++ b/src/status_im/ios/core.cljs @@ -22,7 +22,8 @@ [status-im.accounts.screen :refer [accounts]] [status-im.transactions.screen :refer [confirm]] [status-im.chats-list.screen :refer [chats-list]] - [status-im.new-group.screen :refer [new-group]] + [status-im.new-group.screen-private :refer [new-group]] + [status-im.new-group.screen-public :refer [new-public-group]] [status-im.participants.views.add :refer [new-participants]] [status-im.participants.views.remove :refer [remove-participants]] [status-im.group-settings.screen :refer [group-settings]] @@ -86,6 +87,7 @@ :remove-participants remove-participants :chat-list main-tabs :new-group new-group + :new-public-group new-public-group :group-settings group-settings :contact-list main-tabs :contact-list-search-results contacts-search-results diff --git a/src/status_im/ios/platform.cljs b/src/status_im/ios/platform.cljs index e5aed5af8c..f1d008c2b9 100644 --- a/src/status_im/ios/platform.cljs +++ b/src/status_im/ios/platform.cljs @@ -23,7 +23,7 @@ :border-bottom-width 0.5} :chat {:new-message {:border-top-color styles/color-gray3 :border-top-width 0.5}} - :discover {:subtitle {:color styles/color-steel + :discover {:subtitle {:color styles/color-steel :font-size 13 :letter-spacing 1} :popular {:border-radius 3 @@ -79,15 +79,18 @@ ;; Structure to be exported (def platform-specific - {:component-styles component-styles - :fonts fonts - :list-selection-fn show-action-sheet - :tabs {:tab-shadows? false} - :chats {:action-button? false - :new-chat-in-toolbar? true} - :contacts {:action-button? false - :new-contact-in-toolbar? true - :uppercase-subtitles? true - :group-block-shadows? false} - :discover {:uppercase-subtitles? true}}) + {:component-styles component-styles + :fonts fonts + :list-selection-fn show-action-sheet + :tabs {:tab-shadows? false} + :chats {:action-button? false + :new-chat-in-toolbar? true} + :contacts {:action-button? false + :new-contact-in-toolbar? true + :uppercase-subtitles? true + :group-block-shadows? false} + :discover {:uppercase-subtitles? true} + :public-group-icon-container {:margin-top 2} + :private-group-icon-container {:margin-top 2} + :public-group-chat-hash-style {:top 6 :left 3}}) diff --git a/src/status_im/new_group/handlers.cljs b/src/status_im/new_group/handlers.cljs index 810699dcfa..676707b319 100644 --- a/src/status_im/new_group/handlers.cljs +++ b/src/status_im/new_group/handlers.cljs @@ -7,7 +7,9 @@ [clojure.string :as s] [status-im.utils.handlers :as u] [status-im.utils.random :as random] - [taoensso.timbre :refer-macros [debug]])) + [taoensso.timbre :refer-macros [debug]] + [taoensso.timbre :as log] + [status-im.navigation.handlers :as nav])) (defn deselect-contact [db [_ id]] @@ -44,7 +46,7 @@ :group-chat true :group-admin current-public-key :is-active true - :timestamp (.getTime (js/Date.)) + :timestamp (random/timestamp) :contacts contacts}))) (defn add-chat @@ -91,6 +93,42 @@ ((after show-chat!)) ((after start-listen-group!)))) +(register-handler :create-new-public-group + (after (fn [_ [_ topic]] + (dispatch [:navigation-replace :chat topic]))) + (u/side-effect! + (fn [db [_ topic]] + (let [exists? (boolean (get-in db [:chats topic])) + group {:chat-id topic + :name topic + :color default-chat-color + :group-chat true + :public? true + :is-active true + :timestamp (random/timestamp)}] + (when-not exists? + (dispatch [::add-public-group group]) + (dispatch [::save-public-group group]) + (dispatch [::start-watching-group topic])))))) + +(register-handler ::add-public-group + (fn [db [_ {:keys [chat-id] :as group}]] + (assoc-in db [:chats chat-id] group))) + +(register-handler ::save-public-group + (u/side-effect! + (fn [_ [_ group]] + (chats/save group)))) + +(register-handler ::start-watching-group + (u/side-effect! + (fn [{:keys [web3 current-public-key]} [_ topic]] + (protocol/start-watching-group! + {:web3 web3 + :group-id topic + :identity current-public-key + :callback #(dispatch [:incoming-message %1 %2])})))) + (register-handler :group-chat-invite-received (u/side-effect! (fn [{:keys [current-public-key web3]} @@ -122,3 +160,7 @@ :identity current-public-key :keypair keypair :callback #(dispatch [:incoming-message %1 %2])}))))))) + +(defmethod nav/preload-data! :new-public-group + [db] + (dissoc db :public-group/topic)) diff --git a/src/status_im/new_group/screen.cljs b/src/status_im/new_group/screen_private.cljs similarity index 98% rename from src/status_im/new_group/screen.cljs rename to src/status_im/new_group/screen_private.cljs index eaf2a750cc..cc21d46a26 100644 --- a/src/status_im/new_group/screen.cljs +++ b/src/status_im/new_group/screen_private.cljs @@ -1,4 +1,4 @@ -(ns status-im.new-group.screen +(ns status-im.new-group.screen-private (:require-macros [status-im.utils.views :refer [defview]]) (:require [re-frame.core :refer [subscribe dispatch]] [status-im.resources :as res] diff --git a/src/status_im/new_group/screen_public.cljs b/src/status_im/new_group/screen_public.cljs new file mode 100644 index 0000000000..30116df920 --- /dev/null +++ b/src/status_im/new_group/screen_public.cljs @@ -0,0 +1,65 @@ +(ns status-im.new-group.screen-public + (:require-macros [status-im.utils.views :refer [defview]]) + (:require [re-frame.core :refer [subscribe dispatch]] + [status-im.resources :as res] + [status-im.components.react :refer [view + text + image + icon + touchable-highlight + list-view + list-item]] + [status-im.components.text-field.view :refer [text-field]] + [status-im.components.styles :refer [color-blue + separator-color]] + [status-im.components.status-bar :refer [status-bar]] + [status-im.components.toolbar.view :refer [toolbar]] + [status-im.utils.listview :refer [to-datasource]] + [status-im.new-group.views.contact :refer [new-group-contact]] + [status-im.new-group.styles :as st] + [status-im.new-group.validations :as v] + [status-im.i18n :refer [label]] + [cljs.spec :as s])) + +(defview new-group-toolbar [] + [topic [:get :public-group/topic]] + (let [create-btn-enabled? (s/valid? ::v/topic topic)] + [view + [status-bar] + [toolbar + {:title (label :t/new-public-group-chat) + :actions [{:image {:source res/v ;; {:uri "icon_search"} + :style (st/toolbar-icon create-btn-enabled?)} + :handler (when create-btn-enabled? + #(dispatch [:create-new-public-group topic]))}]}]])) + +(defview group-name-input [] + [topic [:get :public-group/topic]] + [view + [text-field + {:error (cond + (not (s/valid? ::v/not-empty-string topic)) + (label :t/empty-topic) + + (not (s/valid? ::v/topic topic)) + (label :t/topic-format)) + :wrapper-style st/group-chat-name-wrapper + :error-color color-blue + :line-color separator-color + :label-hidden? true + :input-style st/group-chat-topic-input + :auto-focus true + :on-change-text #(dispatch [:set :public-group/topic %]) + :value topic + :validator #(re-matches #"[a-z\-]*" %) + :auto-capitalize :none}] + [text {:style st/topic-hash} "#"]]) + +(defn new-public-group [] + [view st/new-group-container + [new-group-toolbar] + [view st/chat-name-container + [text {:style st/members-text + :font :medium} + (label :t/public-group-topic)] + [group-name-input]]]) diff --git a/src/status_im/new_group/styles.cljs b/src/status_im/new_group/styles.cljs index e18311b155..cf4b583ab5 100644 --- a/src/status_im/new_group/styles.cljs +++ b/src/status_im/new_group/styles.cljs @@ -2,7 +2,8 @@ (:require [status-im.components.styles :refer [color-white color-blue text1-color - text2-color]])) + text2-color]] + [status-im.utils.platform :refer [platform-specific]])) (defn toolbar-icon [enabled?] {:width 20 @@ -18,8 +19,20 @@ {:margin-left 16}) (def group-chat-name-input - {:font-size 14 - :color text1-color}) + {:font-size 14 + :color text1-color}) + +(def group-chat-topic-input + {:font-size 14 + :color text1-color + :padding-left 13}) + +(def topic-hash + (merge group-chat-name-input + {:width 10 + :height 16 + :position :absolute} + (get-in platform-specific [:public-group-chat-hash-style]))) (def group-chat-name-wrapper {:padding-top 0}) @@ -52,10 +65,10 @@ {:background-color :white}) (def contact-container - {:flex-direction :row + {:flex-direction :row :justify-content :center - :align-items :center - :height 56}) + :align-items :center + :height 56}) (def contact-item-checkbox {:outer-size 20 diff --git a/src/status_im/new_group/validations.cljs b/src/status_im/new_group/validations.cljs index 304dfbb7f8..821f267fc0 100644 --- a/src/status_im/new_group/validations.cljs +++ b/src/status_im/new_group/validations.cljs @@ -15,3 +15,7 @@ (s/def ::name (s/and ::not-empty-string ::not-illegal-name)) + +(s/def ::topic (s/and ::not-empty-string + ::not-illegal-name + (partial re-matches #"[a-z0-9\-]+"))) diff --git a/src/status_im/protocol/core.cljs b/src/status_im/protocol/core.cljs index d8c1ac64d4..b404ad5347 100644 --- a/src/status_im/protocol/core.cljs +++ b/src/status_im/protocol/core.cljs @@ -8,6 +8,7 @@ [status-im.protocol.web3.utils :as u] [status-im.protocol.chat :as chat] [status-im.protocol.group :as group] + [status-im.protocol.web3.public-group :as public-group] [status-im.protocol.listeners :as l] [status-im.protocol.encryption :as e] [status-im.protocol.discoveries :as discoveries] @@ -25,6 +26,7 @@ (def start-watching-group! group/start-watching-group!) (def stop-watching-group! group/stop-watching-group!) (def send-group-message! group/send!) +(def send-public-group-message! group/send-to-public-group!) (def invite-to-group! group/invite!) (def update-group! group/update-group!) (def remove-from-group! group/remove-identity!) @@ -51,7 +53,11 @@ (s/def ::rpc-url string?) (s/def ::identity string?) (s/def :message/chat-id string?) -(s/def ::group (s/keys :req-un [:message/chat-id :message/keypair])) +(s/def ::public? (s/and boolean? true?)) +(s/def ::group-id :message/chat-id) +(s/def ::group (s/or + :group (s/keys :req-un [::group-id :message/keypair]) + :public-group (s/keys :req-un [::group-id ::public?]))) (s/def ::groups (s/* ::group)) (s/def ::callback fn?) (s/def ::contact (s/keys :req-un [::identity :message/keypair])) @@ -76,20 +82,18 @@ (d/reset-all-pending-messages!) (let [web3 (u/make-web3 rpc-url) listener-options {:web3 web3 - :identity identity}] + :identity identity + :callback callback}] ;; start listening to groups - (doseq [{:keys [chat-id keypair]} groups] - (f/add-filter! - web3 - {:topics [chat-id]} - (l/message-listener (assoc listener-options :callback callback - :keypair keypair)))) + (doseq [group groups] + (let [options (merge listener-options group)] + (group/start-watching-group! options))) ;; start listening to user's inbox (f/add-filter! web3 {:to identity :topics [f/status-topic]} - (l/message-listener (assoc listener-options :callback callback))) + (l/message-listener listener-options)) ;; start listening to profiles (doseq [{:keys [identity keypair]} contacts] (watch-user! {:web3 web3 @@ -98,10 +102,10 @@ :callback callback})) (d/set-pending-mesage-callback! callback) (let [online-message #(discoveries/send-online! - {:web3 web3 - :message {:from identity - :message-id (random/id) - :keypair profile-keypair}})] + {:web3 web3 + :message {:from identity + :message-id (random/id) + :keypair profile-keypair}})] (d/run-delivery-loop! web3 (assoc options :online-message online-message))) diff --git a/src/status_im/protocol/group.cljs b/src/status_im/protocol/group.cljs index 5de076534b..97ce381d04 100644 --- a/src/status_im/protocol/group.cljs +++ b/src/status_im/protocol/group.cljs @@ -6,22 +6,23 @@ [taoensso.timbre :refer-macros [debug]] [status-im.protocol.validation :refer-macros [valid?]] [status-im.protocol.web3.filtering :as f] - [status-im.protocol.listeners :as l])) + [status-im.protocol.listeners :as l] + [clojure.string :as str])) (defn prepare-mesage - [{:keys [message group-id keypair new-keypair type]}] + [{:keys [message group-id keypair new-keypair type username requires-ack?]}] (let [message' (-> message (update :payload assoc + :username username :group-id group-id :type type :timestamp (u/timestamp)) (assoc :topics [group-id] - :requires-ack? true - :keypair keypair + :requires-ack? (or (nil? requires-ack?) requires-ack?) :type type))] - (if new-keypair - (assoc message' :new-keypair keypair) - message'))) + (cond-> message' + keypair (assoc :keypair keypair) + new-keypair (assoc :new-keypair keypair)))) (defn- send-group-message! [{:keys [web3] :as opts} type] @@ -31,15 +32,25 @@ (debug :send-group-message message) (d/add-pending-message! web3 message))) -(s/def ::group-message +(s/def :group/message (s/merge :protocol/message (s/keys :req-un [:chat-message/payload]))) +(s/def :public-group/username (s/and string? (complement str/blank?))) +(s/def :public-group/message + (s/merge :group/message (s/keys :username :public-group/username))) + (defn send! [{:keys [keypair message] :as options}] {:pre [(valid? :message/keypair keypair) - (valid? ::group-message message)]} + (valid? :group/message message)]} (send-group-message! options :group-message)) +(defn send-to-public-group! + [{:keys [message] :as options}] + {:pre [(valid? :public-group/message message)]} + (send-group-message! (assoc options :requires-ack? false) + :public-group-message)) + (defn leave! [options] (send-group-message! options :leave-group)) diff --git a/src/status_im/protocol/handlers.cljs b/src/status_im/protocol/handlers.cljs index 18549325fc..dd9dc02a82 100644 --- a/src/status_im/protocol/handlers.cljs +++ b/src/status_im/protocol/handlers.cljs @@ -35,7 +35,7 @@ :ack-not-received-s-interval 125 :default-ttl 120 :send-online-s-interval 180 - :ttl {} + :ttl-config {:public-group-message 2400} :max-attempts-number 3 :delivery-loop-ms-interval 500 :profile-keypair {:public updates-public-key @@ -79,10 +79,12 @@ (register-handler :check-sync (u/side-effect! (fn [{:keys [web3] :as db}] - (.getSyncing - (.-eth web3) - (fn [error sync] - (dispatch [:update-sync-state error sync])))))) + (if web3 + (.getSyncing + (.-eth web3) + (fn [error sync] + (dispatch [:update-sync-state error sync]))) + (s/execute-later #(dispatch [:check-sync]) (s/s->ms 10)))))) (register-handler :initialize-sync-listener (fn [{:keys [sync-listening-started] :as db} _] @@ -107,6 +109,7 @@ (case type :message (dispatch [:received-protocol-message! message]) :group-message (dispatch [:received-protocol-message! message]) + :public-group-message (dispatch [:received-protocol-message! message]) :ack (if (#{:message :group-message} (:type payload)) (dispatch [:message-delivered message]) (dispatch [:pending-message-remove message])) @@ -417,8 +420,8 @@ (u/side-effect! (fn [_ [_ error]] (.log js/console error) - (let [message (.-message error) - ios-error? (re-find (re-pattern "Could not connect to the server.") message) + (let [message (.-message error) + ios-error? (re-find (re-pattern "Could not connect to the server.") message) android-error? (re-find (re-pattern "Failed to connect") message)] (when (or ios-error? android-error?) (when android-error? (status/init-jail)) diff --git a/src/status_im/protocol/message.cljs b/src/status_im/protocol/message.cljs index 93d7e2ca4a..80c310e80e 100644 --- a/src/status_im/protocol/message.cljs +++ b/src/status_im/protocol/message.cljs @@ -19,7 +19,7 @@ (s/def :payload/new-keypair :message/keypair) (s/def :group-message/type - #{:group-message :group-invitation :add-group-identity + #{:public-group-message :group-message :group-invitation :add-group-identity :remove-group-identity :leave-group :update-group}) (s/def :discover-message/type #{:online :status :discover :contact-request :update-keys}) diff --git a/src/status_im/protocol/web3/public_group.cljs b/src/status_im/protocol/web3/public_group.cljs new file mode 100644 index 0000000000..a6676dec50 --- /dev/null +++ b/src/status_im/protocol/web3/public_group.cljs @@ -0,0 +1,7 @@ +(ns status-im.protocol.web3.public-group + (:require [status-im.protocol.web3.filtering :as f] + [status-im.protocol.listeners :as l] + [status-im.protocol.validation :refer-macros [valid?]] + [status-im.protocol.web3.delivery :as d] + [cljs.spec :as s])) + diff --git a/src/status_im/translations/en.cljs b/src/status_im/translations/en.cljs index 6449738d00..97e9400ba5 100644 --- a/src/status_im/translations/en.cljs +++ b/src/status_im/translations/en.cljs @@ -27,6 +27,7 @@ :members-active {:one "1 member, 1 active" :other "{{count}} members, {{count}} active" :zero "no members"} + :public-group-status "Public" :active-online "Online" :active-unknown "Unknown" :available "Available" @@ -119,6 +120,10 @@ :chats "Chats" :new-chat "New chat" :new-group-chat "New group chat" + :new-public-group-chat "Join public group chat" + :empty-topic "Empty topic" + :topic-format "Wrong format [a-z0-9\\-]+" + :public-group-topic "Topic" ;discover :discover "Discover"