From a730c884917eca072541d615d6b1c1dc0d6b10bf Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 14 May 2021 16:08:48 +0400 Subject: [PATCH] Add icons and improve narrow participants column. --- Telegram/Resources/icons/calls/calls_more.png | Bin 0 -> 277 bytes .../Resources/icons/calls/calls_more@2x.png | Bin 0 -> 444 bytes .../Resources/icons/calls/calls_more@3x.png | Bin 0 -> 653 bytes .../Resources/icons/calls/video_mini_mute.png | Bin 0 -> 436 bytes .../icons/calls/video_mini_mute@2x.png | Bin 0 -> 761 bytes .../icons/calls/video_mini_mute@3x.png | Bin 0 -> 1138 bytes .../icons/calls/video_mini_screencast.png | Bin 0 -> 288 bytes .../icons/calls/video_mini_screencast@2x.png | Bin 0 -> 403 bytes .../icons/calls/video_mini_screencast@3x.png | Bin 0 -> 639 bytes .../icons/calls/video_mini_speak.png | Bin 0 -> 560 bytes .../icons/calls/video_mini_speak@2x.png | Bin 0 -> 1058 bytes .../icons/calls/video_mini_speak@3x.png | Bin 0 -> 1533 bytes .../icons/calls/video_mini_video.png | Bin 0 -> 355 bytes .../icons/calls/video_mini_video@2x.png | Bin 0 -> 480 bytes .../icons/calls/video_mini_video@3x.png | Bin 0 -> 729 bytes .../Resources/icons/calls/video_over_mute.png | Bin 0 -> 596 bytes .../icons/calls/video_over_mute@2x.png | Bin 0 -> 965 bytes .../icons/calls/video_over_mute@3x.png | Bin 0 -> 1529 bytes .../Resources/icons/calls/video_over_pin.png | Bin 0 -> 413 bytes .../icons/calls/video_over_pin@2x.png | Bin 0 -> 672 bytes .../icons/calls/video_over_pin@3x.png | Bin 0 -> 876 bytes .../Resources/icons/calls/voice_minimize.png | Bin 546 -> 0 bytes .../icons/calls/voice_minimize@2x.png | Bin 1001 -> 0 bytes .../icons/calls/voice_minimize@3x.png | Bin 1409 -> 0 bytes .../Resources/icons/calls/voice_mute_mini.png | Bin 521 -> 0 bytes .../icons/calls/voice_mute_mini@2x.png | Bin 1023 -> 0 bytes .../icons/calls/voice_mute_mini@3x.png | Bin 1464 -> 0 bytes Telegram/SourceFiles/calls/calls.style | 90 ++-- .../calls/group/calls_group_members.cpp | 498 ++++++++++++------ .../calls/group/calls_group_members_row.cpp | 264 +++++----- .../calls/group/calls_group_members_row.h | 54 +- .../calls/group/calls_group_panel.cpp | 10 +- 32 files changed, 552 insertions(+), 364 deletions(-) create mode 100644 Telegram/Resources/icons/calls/calls_more.png create mode 100644 Telegram/Resources/icons/calls/calls_more@2x.png create mode 100644 Telegram/Resources/icons/calls/calls_more@3x.png create mode 100644 Telegram/Resources/icons/calls/video_mini_mute.png create mode 100644 Telegram/Resources/icons/calls/video_mini_mute@2x.png create mode 100644 Telegram/Resources/icons/calls/video_mini_mute@3x.png create mode 100644 Telegram/Resources/icons/calls/video_mini_screencast.png create mode 100644 Telegram/Resources/icons/calls/video_mini_screencast@2x.png create mode 100644 Telegram/Resources/icons/calls/video_mini_screencast@3x.png create mode 100644 Telegram/Resources/icons/calls/video_mini_speak.png create mode 100644 Telegram/Resources/icons/calls/video_mini_speak@2x.png create mode 100644 Telegram/Resources/icons/calls/video_mini_speak@3x.png create mode 100644 Telegram/Resources/icons/calls/video_mini_video.png create mode 100644 Telegram/Resources/icons/calls/video_mini_video@2x.png create mode 100644 Telegram/Resources/icons/calls/video_mini_video@3x.png create mode 100644 Telegram/Resources/icons/calls/video_over_mute.png create mode 100644 Telegram/Resources/icons/calls/video_over_mute@2x.png create mode 100644 Telegram/Resources/icons/calls/video_over_mute@3x.png create mode 100644 Telegram/Resources/icons/calls/video_over_pin.png create mode 100644 Telegram/Resources/icons/calls/video_over_pin@2x.png create mode 100644 Telegram/Resources/icons/calls/video_over_pin@3x.png delete mode 100644 Telegram/Resources/icons/calls/voice_minimize.png delete mode 100644 Telegram/Resources/icons/calls/voice_minimize@2x.png delete mode 100644 Telegram/Resources/icons/calls/voice_minimize@3x.png delete mode 100644 Telegram/Resources/icons/calls/voice_mute_mini.png delete mode 100644 Telegram/Resources/icons/calls/voice_mute_mini@2x.png delete mode 100644 Telegram/Resources/icons/calls/voice_mute_mini@3x.png diff --git a/Telegram/Resources/icons/calls/calls_more.png b/Telegram/Resources/icons/calls/calls_more.png new file mode 100644 index 0000000000000000000000000000000000000000..1bb29b885f87bc32a08bc445582c2cb9932b067e GIT binary patch literal 277 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uv49!D1}S`GTDlfU)qA=)hIsJ4 z4LZnsK!L+%_CMM4ymxvR${gZcA@TA04}~NADlAW*D714j@Rx5s-dic?-n{sb;>Fs| zI9bK#Jwd1T2nklb=Q^8luu`NryZ7o7ot+15?shb1uRXPQ@sll$tmXfgEn2_YCG#Z1 sX`$3p`+wbakgJ^Wn{Uy6gB0F2&*1?oQ}c9j49Q@9 z8_vjeSV3U(?{NET|5m;KAp6(#^_dr2WM6SL$~p0+ESmmWH88QcSntTi+&#PA{>g}8 zStC1zxu_w;!M#IdLfdJ^D5p&gG779q9u_rBo1mk>?!lP3LuP@h3b%-?#PN%|rypG_ z{mXM^W10E9V~_0%r7oMa*4{sypL1JmL-{$~v%DX6{#+5`uz2eMxgxLL1O;oXUK=^}|aKiCCv^ zzkl+%OiP^i{E>IbcS+L&@th4Ta}IPjd3QEezW&Mb%x2yZ{^RYB{pT0%JYpLpz?gmg t3DDJ|7X+2CxcmfTkb{&Sdj{u8ru^KCiMRB&1xSNJ&ePS;Wt~$(699B@pVI&U literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/calls/calls_more@3x.png b/Telegram/Resources/icons/calls/calls_more@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..e400631f4b6172aff697f09676a5f9ee3f0af22f GIT binary patch literal 653 zcmeAS@N?(olHy`uVBq!ia0vp^9w5xY1|&n@ZgvM!jKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(<^v49!D1}U6i==L6{?7OFnV@L(# z+gXNvhYSQ<4`;2+v|!j$z+<5zYW`5CL;1p`6yuCwm1DnURF;_9cnfy@KO?aJkA+#% zH51?4vfFqX*Zb_hyPt)HB}`yKLj%JJD-Q<;h7?&91qFspd_n>O43X@d92^a6nt@6j zt~oL>F)6%OU}R*RP>M@A{AN%qZI(yE$(C`{&O;@3frjclK+QuIKR?|Ksfc z?fLK_LT~!phXon=+oP@XE{aDTdGcxH{z{&(1 zx3T#7YbPzYSh?w!=7NfnW!p|j?p7&}i~Os&An#C(#dCoTGbSsUvoC$Wer?^SS@++6 zKU-t>{+RJvSHC?kS6mIVXWSCCHlrtUZ#-KHv(>_Fzc?4{XZzk6#iSwDcz)ZYJCkPI z`9A&0v?D%i?Po+}&vw~;aNn0-!t6)CJ*=>KrjY(yd3nm~z~sLNWjm~cZaTfYdfk3Y zM*hvWWzkz^)s?Ld4E%e%p-TPes_&D{S8t9#ULybVn(rO?-^K2N3v70M51+LC#&7=0 mTO6z`dsrw4R^(Vw9yeF#n@q*Ue+xrhG{3>jCwvX{&e#2vnMeDNnWyglU_3LzGUMuy-V&3zM z``(w-*nO(~Ut@EVftj6m%W;O8^LsOAZON5BT6o4~l8OlrvwD@p0ib#_28U^>TXeWv z6IXEUU}xi#I@yp}cD@`4a>;{FHr>mdKI;Vst E02y_j*8l(j literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/calls/video_mini_mute@2x.png b/Telegram/Resources/icons/calls/video_mini_mute@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..358fdbfdd415679a500bae666d2afa5145f7f4cc GIT binary patch literal 761 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdz#^NA%Cx&(BWL^R}E~ycoX}-P; zT0k}j17mw80}DtA5K93u0|WB{Mh0de%?J`(zyz07Sip>6gA}f5OZv>fz?AIi;usRa z`8LFMyD5-1y!K&5kxA208ik(v6Mb8&5oj+#m zKHq8i-fH*tyHkI=-FxC!bY{-X^m&!v-pI*2aTr~@{pS2_wfpS<=QDA&HoYj@owWPz zsaA=d;k@@79$(Ec0g6n_JF)Ot+v~nkyFC#)uZnf66Jojw^b$;@BH3PXCj9GUn19~= z_~XF&={K2~*8~gp zVz1l+HXi9J<%u14jMT56xmRSeG>CJ#+S;I%HdnH@N=f=3PJKGj`K&@1_uiZbCf9vF z-e>b;V`9AZwro@R{`-?ZitwM^8Pj*`t=ZZz?VSS3$NzqK;i%6O161m}F_fX}X;Gxv z<8%v|AOnd%T?Zzyi`nKpFyg(ET+Jxg-_F*|SbQPHXkm)cO7rM%2Yi+XUuEYj*eTY~ zR$$@Nebi~@nixB?r=zFB`c3+zO=0+(M-^m}^#xpA(U z^iF}-ZE|0X&I|vKVK9HBJ@5SUUoxlVW~j&SnX8b_6yc#Zd12O8ug4!Fc-?zsvU-Xi z-sMb4`Ye0>zqZ8VBe(wvOZDEL_3@tQF`3m%x*tqUUhJaec=~CO-jQQ_re8b0_hRe4 k`K|l@aMgJoyUkj|B=cc@FVdQ&MBb@0JaWDEdT%j literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/calls/video_mini_mute@3x.png b/Telegram/Resources/icons/calls/video_mini_mute@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..4be74a8d73e63c84ae9bfb093c54c6e5a50863bb GIT binary patch literal 1138 zcmV-&1daQNP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91FrWhf1ONa40RR91FaQ7m0NXcg3;+NF+(|@1RA>e5SkEhcK@^|&BDN?$ z%CE&^VW%j?iX?g~r6m3X%EpGWQdXku?bxv(OBQUE9pzCXKk}3k7A($pKDY1O?#$eK z-<>=6^{97hnwc}_e9rmIulpm#7$aW(tfc>J=Km8f6DaixRum(FnwlCmI5^1K+uI%Z z+uK`qe0w&>^Qhg5+MW3WjgmIuQ=ae(#q_R`bSlbW~I zhYf5!3D~yn3Gl5#`FvhWHb?*qi= zo8>vg6B}O<(V9RelMz_PwT-U`W=#Nheq6Ef6)~*|q*5t?WnA0%ieT0R1W>8!GJ#Uf zyog&~0WlM$s>>@-s+kvY3$8$GYb#q^Tx1gy6T+wHHDV!VOG`_nSb;B8)z#H>e}C`3 zlg-Y~YPQ?k+wQn&1HL>%sm#sIxiE;098?=`KXe5;IyzW$bF(`OV`F1(TQnXYA4Su+ z_VXPb9d&UK8##nYD1q14SIHOKNtKh66IB(t@8{dr)+YJ$j~}V;*9lyrbUH14-@d=U z6Muh^?6JfT4-f9LM{U4I-5$V33?cZAMh-mbuo5~*xm-@*Idy-3zXmolGb7nV=}b>g zYd8Y~1Cs02)s<%BLnfTS+S-}~y1BXO3%aqfA=!m>*4Nj4F@WtA#P&&8)rAx2>+ADk z(%07)@w1?UIQ{wgdHVSHknFu3jKRh)DPRKID~Ro9tLVZBU|(KbTzGM5cXu}s82^2i zmX_%B^px)I?wo=)bYcI5_V)Iq7>KE!HzjeALpT9Ajf{*);OHzbFAD(c8d$0zW4Z`C>R(vu=U>e0ub1UVUiQR$Q>5EjwIdP-HabN#(xcJ z_B;`Gc6P>&j*b{V!0h??*|BMCY-D(f4-E~mo}M1Y52xmfKiK2r%GA^p;pX`K z{47WYHn4?Hg!i1Fq`i7O0)hzYs;Vj)9v-IE)m4oMbQpt;*C&B?as)&&{Ge+DpcCUs z)}h}6JkYO~q7eB0{?>^5=`^F5io}<;va*t{udm&0gf?_Mzr>62gDmPK@z(*yZyLvZ zXJ?1Kyu3tpHL@!j0i!G|jEiyxEb=jSEfX-FvVz|~s=uV{q6GQ6#ZOPJ+jrPhLt~q&ecC09V zerHRx+@cD$$%fBPeXSAXp3!~7;+RCLeblB&&luOdvE*P@Saf1~^T|V|S@-`raX5C$ zA794mIyErk+VNEGa<4t#c^?Nj256gA}f5OZp6?{(8DNhD30_ z4L!}Mw6QnJG|i zxA}W*{*o!036{nCS#_%OXQ{Cpl=j9mJg;H99JPL(&ZD3#E1@&o^EcEoo}Rd5Lf-RV zpOjung@v}R{20xlIENvSX^uAkD;=hHFArGsvCsWr*K@gXTkgYnC5fyh>`D?9%bOo> zZ0-@9E9=MpM)Uc$d5RA@YB&;q*mZ85ZzoiBx>)&(q^s(~nUNoQWHk6h*w2+b;9X|? VcxSZj+-y*Qc)I$ztaD0e0sy*qh(rJY literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/calls/video_mini_screencast@3x.png b/Telegram/Resources/icons/calls/video_mini_screencast@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..082e48f0287cc82e9a69b8a34b3c43c27a1ae657 GIT binary patch literal 639 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC#^NA%Cx&(BWL^R}E~ycoX}-P; zT0k}j17mw80}DtA5K93u0|WB{Mh0de%?J`(zyy~ySip>6gB0F2&*1?od+F)o7?Q#I zHo|sYlY@ZVS#OQZH81xxhFq&)^xoSd{(&pb$G4_n z*WC2w_-*~U_Wqf+*eZqz-OsbV|7TAWKcL&_?|#AUfZKwlOlGZ7TsNwIUUz@6ypyH* zAVZTv!@~lOzxyQ59e*siNTbQbceX>oxr2*c-YPddUw&Ehxklu)r~BSt{}uLd(y>C0%w>R!&_UYEGTsqTF2d(&By)oj- zIniTwM$7I@{M2SE!?z)7t=FZwmD<4`ZaeS4f2vk7kNxsXk(leXugotV*y2<_`>b2` zI>W}>Z@(F|Jup;~c_8oSqRQhuU&^Z~pzQd^`QN3e%la zry1NAPrS3{iYJR!n1r>=@xZ9}HjJuOh8dhML>|d)7km&Fk^aBlok3qVR{s>ogWi`l zcIC60Co#l*SDSqD@1Oifcg`(r`DU>F_S*y-x#AyYNx_ng%5pP$Bbd%GWuKj_^kKSm z)bnna2VbjJPF;DlMQxu)z3{cyUoXpZ_p$vFxHHv%{S1do9RH;s_Ij4TthoNedit+0 zmV2zn4CilQw`d5+jbaLU>a%vUputj=t9`u;p_aj~b69*dJ-2@5o|nzI>mzTF4k+?H MUHx3vIVCg!04M?n%m4rY literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/calls/video_mini_speak.png b/Telegram/Resources/icons/calls/video_mini_speak.png new file mode 100644 index 0000000000000000000000000000000000000000..af740e57e2570b7db3843159af0f02ac49ab2589 GIT binary patch literal 560 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uuz(rC1}QWNE&K#jHp|n+F~mY} z>ZJXr9TP>4@1New$jrRhXmjM7Q}zi{X8dJjTYOTq+c9jiqoG#hk{lx~o+&|M`zOhq zFW&S0rCkO4_IJf~cRyP`xA`u?aN=zlH{%>X^=bR%u4HXparxy0k3T<4Ph`FRD%I)Y zr2Xb=)y3Ce3+(0_%J2ztwQkvQcR`Ag=O@ng!>gLTmL9Tuow5D4mfEDL=VW`_lx6tX zQ;Z~8`&^W~rk~oK%Wrhn#P`GH_xSQ4lA5?G$}At^kmuJ)E_l=QF_x&X8LFd zaC~5YSu$(ZS+%D{mPR~>=PfCD+<#2gb#dUA-?bKV{jR(&Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91AfN*P1ONa40RR91AOHXW0IY^$^8f$?j7da6R9FecS4$|iK@^_vbH8RQ zk&Rd&Bw4T!O36YBYmzKjT3FdwC`%=aZ!H!S8_9KLVc{O7w_FaVPT<|o0}6iH#g$p;X$mfu8O+4 zI`$DpkZHzU!1MDnP&++6^-O(zeLcLqyhyD6^Y!%w{r&x(wn)sn{#&uMw8Z{$b91dg zIZsbdhx7Au##x28w>QA-INCY{2R;Hy+4}lA4YD;gH7U^;YinyoUS6J|(r!27!fz1qOF^cCxGs#l^+?)KLy{hm@f~V1IvKsLMzfit2*3U0hsPRknE$jBaF{ zS8s1GAM5=5ys?Hxkdu=GudlC+aS|FE8*O%E>(b4I#Kc6v9kAcNzCN4b;NT#yTZO5q zDI4A;u)>)H2;9)nAS)s{r(0cFS*gH0Ql_4so;d!;#|Mm#jsjjn#`pwQI6DC{93CEK z=Tsl?QYr%;6A}`jqM`z7YHA=YEsga711r2U0W8a~xVXq9NQlK^P*hZ;48LWhB2JDR z8}3kyjg5(cfdONk>c#T%vcQ5QE-xsj1N2-R=7bIuYC0*nsTpY{Q>MC>Q}{u(Pw{6vL*& zV*+|PskXhn4YUd6M;pTt*xcMyK0U{*tSl%mFNc$p6UI$WPX0ZCm6a8C=p|%iWXNFn zp#yh!cM?jqqM)F_AYr@e((d zfv`uQA}IniZ*6T=Y7v@1&Q z{|mtN^|ky&KR!N&@$qr+`d8J})x`vwo16cffR#|tIen~5PfyEEpZ8?v`8r0xkGIg5 c@VgoP0?_(?w8MEkY5)KL07*qoM6N<$g6j9$;s5{u literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/calls/video_mini_speak@3x.png b/Telegram/Resources/icons/calls/video_mini_speak@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..ef2f53ed091e33823b6409ead45844ac01aadad5 GIT binary patch literal 1533 zcmVPx#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91FrWhf1ONa40RR91FaQ7m0NXcg3;+NHXGugsRA>d&Sz9P(Uld<1Gh{+Y zAvH~uNr;dr@<36N%aaTyxAGwGNO>U-O5{OFNbz85L`~ATgz})MX?Pf6Zj{EQW{~Ti zwZ8xC^FRAL`+Vno-~af}XV+=(wf0_@-#+WCeK{Tg!0>sr#q-g6{>O1|djNrfflyyx z4~#Jw92|tRvorf4ZbwrHDbM2KBKrPMSy)(5`06ok*8bOdA0Hp?yHbaThr2Zh;TyQR zx`N~5V=;Zk`Vxq#D@l5JHIb_Vy~_LyeJ<5uqOqI;6e5y;*yEJG;5L5%j2u>FH?}78d4EkC7c!zvxg+ zO^w2=`(v3OpPyVYisPulP6qQQ+IT9Xk=szO1X|g(h>lqgtij) zrKhJy<2X0y;o-rWnwl8yeeA^)dUSM@;kiRs2iIk?)_((}ASft^9UdMk#(AT;xtWo( zdPZnP9~c;5pFVwJKY#vY-@bignB7=GL4mG}o-PBvV*n(alanLeoXyP4*Z>+Bu-ajJ zeZ~OD!RqR2KKVkux3|Y=5A+v7m;*o#Ha0f0ySqC904L_>=UGuv5yM6Ae+A?5XXdan zSBi^^VQg#+{QUf+0vPYGy1ELRo15_Y^JgIX`uZ9$;{awaTg}@z8Swr4cli4CE8w;r ze*O9-)oH|Zdd8xoqZyvA_~ctspP!%GG9IOFbl924slke3Pft(VcR>dps|#hTkdP3? zmH{Bw0C1(aC1z!1WsFv7D+{IFjEoF3ApRQw4rFd_&Sn2EFE6FCCnqP2!j;>Q)za-W z4s^Pp6Hd!;frNwvsI9F9Ov#*Ot8ozp+S(hPMI0hTO{V%MCMKk_XokseC;|ck*qb+R zG$P&I-Hv=P=b#agp`js-VY3YNmYOz-c%&6XDa7>7&TbJxv>xz+_ep?B0n{N$CqmqN z@gYKO834L@bG4`ekPf^Rf&Tt}L0w&49Rvpl3p^s+0)XsX+||`3tju)3T3A^4Z~)Y= zTw}$6VgCkb_>Uhy;O*PDf@EoFsX!Cq7H>cXfSkjOM3quDgw_LDhePeDM_F$ z13;}iHV626%_?|9SQWK4?_&_ z*OEhUGPPAzRWLj}taQD8{TlGXO`(<7fgHDN(*;^vTbu11-rCyA=s3%LeXuv6OwR*1 jEd2%^*jK6gM-SjP9))8shc2vr00000NkvXXu0mjfGyba2 literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/calls/video_mini_video.png b/Telegram/Resources/icons/calls/video_mini_video.png new file mode 100644 index 0000000000000000000000000000000000000000..7fb85a5796dc44a693f478084c7d8e065d2a3b8f GIT binary patch literal 355 zcmeAS@N?(olHy`uVBq!ia0vp^0wB!61|;P_|4#%`jKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uuz(rC1}QWNE&K$e&U(5yhFA#h z4cg7yV!&g{{`-P1|GpOoL;77;qN zoALL)`bR?Rww4{eQ7W5w*g(L|cE{~~)n`7>S+FcKVb(Hlt5uz;k#Q%?I)pfGY-D=9 zi%sgu0TWG+IgPdVHRn8+JXUD4{DrKon6gA}f5OZp5{=H=<)7!twx zHq4N(*?@TDS_#ua+#T!%De+7vMU6VSUNiy@9YqG+!i(^Of$4~=?OKf+tZs> zBAhrTJT}-ZbFDJ3M#w_+hb?Q(eeu-Du5G!j3^{y96y-kOGqqvQQ|4fL@jLF@-TWEq zo&ma{ldI2vK2RtlYi#PiAm-%1b2`kQE1l)s16d9mIE02;r70>rO?mpQea89Ot1SAG zC5}(zTJ`g$J`2Z3#|5J8CcfcUO?oVuJSVN0^_WFHK~r+c{@RZ(>q9hhLwvgPH(an^5>kfr{_v-z;#niJK;zXgId}4M2>Z@?bI83KKQw-#?{JpIRCk} xzd_A<;tuOB)fcbRN~HH~nl<^r$^#F%Vi*nES6K?mygv#GT~Aj(mvv4FO#mYEs7wF= literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/calls/video_mini_video@3x.png b/Telegram/Resources/icons/calls/video_mini_video@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..34f1f3f97d9dc9b1acd1b9084842866420496c69 GIT binary patch literal 729 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1|-9oezpTC#^NA%Cx&(BWL^R}E~ycoX}-P; zT0k}j17mw80}DtA5K93u0|WB{Mh0de%?J`(zyy~ySip>6gB0F2&*5QUU~=|!aSX{| zeH*dy)FA_beXriXc<^Y=gGI9+2wVJOc;~l>BhPAwWyb@RM-Lvndf?5`w1cCskM9=) zSJ$J2e=h%~U1O=fxUIg0#Y_L8-uK$_+!J#d8CvY(t)1e#|M2fn`*2_KisS{!9|lan zgnt<{$j`2?Wvh#8Jz&7&vHbFc(@zy<`Y_Et-S_z?&+D&JVXH-D_}C+hr`YZGD)3jD zsId8FPlc)9a^aO>t6SI_KdXMy->Ak`ZzH$&(7PMU@4x@;-QarS^a<+=mrwq!Q~y~b z=esCCW5U@qXR&V9&f|}jtkc;x9M&$#3()-(I_eZT|d;C%2(8CSdB7Fy}-IuNw=WI>e z%-MX9p*E$MMWv>4-L0&x3vR#ldb^sZF~^MiZCNyzO>kHngKdXv-HJu-DidU`TT;Tk4@}hGM{*A8rt9{t?rgKYei4BxwI{oxgAGfZybAsLc!x<({ z%;us~6%R0kYKcnlwX2z3nXT-wntjSbd9O3(yS>V-WWRiqX?$DOZB`e4@hto9sb*5V zSH8(GUi|3uOegj+<$*EZ@co!kW-CQCsowE zzoVr4v%@P_wCZf#RsW(g)qfEa^D}cc#ywQ#{g!`fN@VSts_c)djFUS~<-ZdNl3c?v zTTP+MYeKdav!h$|6Yq2fk*NyTOW2xvww<`HKe1s(gRyDBQ&6(h*> ze%z-XKBM^fj@Y|--`B33`Fzgv%5yV|<5(F2Z1Sz;^Mm(s{8w&{(PO{-Qe@g`)hn+{ zKm7hX?f*KNO)n>VE&cG3hmCp5?YGPJbg$dF!zar`s{hv)*7eeztKaV%2Z%hqnsl>fTXTU0PxnzKrHLF9&1Um@-^<(H623ZgMTk}oU-pBt z-3K3kbWob85VZZa>4fjUZF}65H{8sb;G=f%^;fAPJI2GScE;$5Tut13bIA;Y!*%=X zW3L{5*zmJvUed;ho)1YIGcE|S2|a$_xbC$}Na)m#ML|8sAJ6bx9=Jv~(Qmo%@yCYi z!d7b^d-0KNlFdw?g6+2#F3WsTVDU~%t`|h?1m7nL2tTEccYSz<(pZjw(T&M;Y+le-z=deo@Q7XyOP)J7xM#e*_z|;-%HP7)YzH+ UK-=m;C@4lfUHx3vIVCg!07^Uew*UYD literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/calls/video_over_mute@2x.png b/Telegram/Resources/icons/calls/video_over_mute@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..3d65f89b40736c782f150c8b6baf83725b05a956 GIT binary patch literal 965 zcmV;$13LVPP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91FrWhf1ONa40RR91FaQ7m0NXcg3;+NFFG)l}RA>e5SUpcFK@=TcEGbY! zK`iL()IDG0_+c(MY1>oQ=D0W>^?z znSJk>w>O#0+^=)*nOTa2wY5bs{17kLS|^Z5 zB*??VgEg?`<@58CSCwlyeiimAFf9W4e4a!i5o=srTnM=A`9{!HiX0C-8yj`j6)ghK z&(98SJRWz}Slry)2)as<<9R&3jtWPM!0qj=gD1b7wA*bm9*-UWss-X&t(FkNFFuGzrS~4_yz3n%XNTb3-D#XLf0cuDwXV7^yA}$o}8R46lBl)v|KLJ>+5UU@As`4 zI_z>Y$On!sz?Wkbx*maWI85*E?(BMWGMUi5y*=HcRy^{MZwqjNuV`5I>k$BWE|;@w zTJvBqpofQtGVn_M=;(+dj~C!-Hjj9H0?4_#y5ehFUm_}%3T5~5l}*5pIQh#3@VxYb zw-Ad3o3#WlB-Lt_6bc0)@8#u%bh};B>-DVL>eJH`+1c44xX-6jDUwd73A;>$oLa3$ zip3&fJ0jTERXj0g;8xz**%_V9X2NN#s~`{gHkQZP+a<&oi^XEJUawR36>hEG5r=r> z@i-pWn-j1L<6F=9`8j3(vUD^W31pzd4!@~yLf>`G5wMA1X4ktw06OnCwbptTVnzQs z@r}US+nYdE)&=K=iZ4gY-mYk;)1mYE+?t`YK8+90{{tItnz3}>E+JzbDu4n4iVgDJ n9h`vgTdXJ$oPc73e0P5VR-~jN-}_h&o!wDrH^O zIKs4aOY0U9N}_@)s%ah7y6Qd_tDzhJ?9S}WzM1cR@Azik%$s>H$=Qj3kW!Qa003c6 zv~d+NaUU=VktZ$I5JUuqxe{-J^}6-KnqcTT5jsY!#W-`k~&cc`;nUcxe{ zrsAf73TI^wCjbOJP3{o**UnBxZmyz{nVG$llM{D-Ubms8MLRDqucWCdPfJH9tZ^d7 znDtn3?NNC-wWbF1M;5EK^^%{TI1Z0TtRh#B4H%|KdwQXiQ}l@r4yQO5c0pqk6AZ9` z%r7j&d3fZErEeU_%*+(`@$uPQaXyJLH{baxamvc7awL>Mr%)(SxB&xNNYSoP7*3DB z{FcQ!JqpY?ll@S`yG``0%^#3U*CTk5bimN1yW(14C@f^qi1weA49KRJ zUyw}g^D<^7Pn@%nkvSW#o2jIvl!JY@s=97hT2-aLw!M92=XykhR49IZteeB3yG|oVk-WV8ne5!X zCskFjT|wK3bKo0+Ntp~mP5iL=PlYrZEwQz=wSgPnQeDmA?rAvJ$jZsR$f?;(InGAH z!0_1E-czy)3Ow%S))sGUOhxmCyCD`^=3!gms6Bo}_Ytf>0&Q$eddf>pm9}kY;S>}o zGbD%=j+NAY1IIYjuxPBmMAzzSsBKetG2GwZKWA+dHa0%4Zeij1N`KdepTl0h0@-0I zJBNfAPV`(ZoHdDn9X#kBZm6aPV6oVqJ7G^&gNP(j7Q>2e%?$6fyL$CWU?h}Hfzng> zeSH||&5ez6bE5n;Lrcq^K^K|+TSukfa8hu5LV}q07ef*TgCWh&N+%Zf`zm!1H1zd* z%kFJ+Cq8bkt#JmKapuozYas>5U;zq+^8Gwn7Za1O3_Lu4-a$MvDhg8Y5Jhw?gZ|}7Ns{cgi|)~6GI?cXh0Sh@Ln0^ukV&_cw9P$Kp=7#bl+P)MbZ%+ot+#$AF=aNtGOMI z$G>lTCvZ{v7#I`;LVccpD#0Tr!AmnC$t_JyZu58MGP@=xHBMo%I2;b51_Yt&Q%~sW z#qaIKF1c8F8KGM~c)k#g>uL(fG~Hh@vl!3`SfKw6EA#ee|AaT|7Qt zTV!Qc3(d`zIA#d^Oln%1BeXj^JDaz#@OZAM!4@nq@=6{&#LRAJZuWyzuvlYri)%aI z__aGQk5PyinZwYgmjGj4p_8Po;Kt=avO$}1wq9fMgX_b?!zcah$OlznlrD7*4aoHL zG+^>}*3M#ZXsChibK7y<&Ni-iv9U*Uy8L5QRyNhNL|aWV5l=0?kNlrQo&Wt{NoQkjw4&Pc6aQwX8{G^PIr#1N4y9}Ro4rMSE~m`tjG0?@qUe+C f{i<#`rpFO>OSULR9}F)!0ty;WS3j3^P66gB0F2&*5QUVB+$0aSX{| zeH*@e)gcFgxgH|g+}zxbAu0)){~B8rw$(NEw)WO1W+py#k65yC(V+7E8aZjs#}dtpt3tkW#k zD`nedD|8c;CN|XV=bwF+P2l78S{u28-)m1iEn2Uqa{gdo(-S$q_MY$0v$sYi8qHKW zS^nJD`Ce(P&HVH8Z{A(=bUa8u?)+U5gV+9oPqOD75VvAC!mD3qC4W8TAKrlT>l zVS~%EH(?DcPjwyJDl4#dil$5?yUlswXAx_|S~n^=y!Blgpz)w=x9F`Satrddubw-- zlRN3f+aoJOxTc?e+C2Tk`=><*tM>XSI>kB^)XeZ(erU=4#`eREr=MC^v4Q8J;kn3OFH9`lKf=*2W;+Qp=e z92;j$(k>58(U!da?WBN=BJ& wwO$Zn=A?d`@lcXh>n7O%E$M~9Ppm&MXU=S?yT^W}5R^JRUHx3vIVCg!08?u6=zw%v~^|klkBNqlFn9c6xaGkeiJ-eo@@l2lk@4rile|Fz~`)S$k*i7sDJ6E(m z{{H)C)>b3`XWr+6R(|=bR@3imj>k_L_K98RgQ#@33_{AoAv{demJN${YTE7decv@=k<8c)_l-`gJ-eVrkiVWJc?wN+}?jR zOY*3yPHg;bzokJ&iYFOER)(}VF3^h75sRt*bGk`IEGSFFM-7>VnOw8aKKsm^Wg?Z9G;z}NqMaWCG*m<;eb{*;#c1M(P5JA*-o|#Xy`Eh> z)A!l0T%-9fbFOB6J#SWIBNx6acF*0s$h~ptzsk0raK8WHnr`RehK3J%X$AAA`-4h4r31sAj#F8%v@im&}}XzsP;akFz-{y?P(l&KSL)FH0WH s^>e@W>cQEKNoM{L!pX#?9;g*{%-#~e7$Q<4SA$Zzr>mdKI;Vst0BGK0mjD0& literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/calls/voice_minimize.png b/Telegram/Resources/icons/calls/voice_minimize.png deleted file mode 100644 index 85c36639f6fee32440d2b5c9374718ca17298b46..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 546 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uv49!D1}S`GTDlgftjE*EF~o!S z>J-COha3dj)H{>ZvjmF;PR~(bVG-Q;Rf^G3KPf#kGdWj1Nzh4eg4YHC7uTbe)~CHo z&f1;H3fj|pGHv?Y|FdVFabspk3A=HDJNTdIKl_HLwQSu-nWmjq&6uSo(zfqlc-Z>u zgy6`5W)Q|J;$O%)yjn zHhcY}En%k}u9xyv)cx4kzby0Ak@tZi~{@bonWF=Y9E& zyzNfXVXH$Wc-Rib?OD+FH1mjb281Irt2%!aSorW=_MPjab}~xv z3xiAG5#{eT?}Il^nP0#ku_QoiYJ%D9jS8P7nH1zb16_Z{tL)kzFUt3W(egdV#mF1> Q|3UHN>FVdQ&MBb@0Hu!5$p8QV diff --git a/Telegram/Resources/icons/calls/voice_minimize@2x.png b/Telegram/Resources/icons/calls/voice_minimize@2x.png deleted file mode 100644 index 0705454d8e288dfd2fd204c11b4ad74d70a6bae7..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1001 zcmVPx#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91FrWhf1ONa40RR91FaQ7m0NXcg3;+NFQ%OWYRA>e5na@iyK^Vu!ADKZ2 zVRh|bga;)g1i?!XBGI8sAVLKBwHj<}Y>WX84h|IIPfkt* zK(*X>0YuH?<0GWgX&^HUoxZ-l;Q07h4Vt#=FTifM(~QhAfse=IG#pRa90EQ+KOq*2 z@c>JG^cS$Ou)u6}!H`O&q+qSa5-;F(j?7t|F_|itq-FdEtc(;ojipF;oCIl?F#chL8px&8~JWci=4n!qXhW zn=|G`h6mo~XbC&BulS3`k(lLBCvySqCjR>e9z+n7rLX+gK!4fpr=iokRwd7IL)#ig@Yg%nJdLict)Z2b70ks>cyG@(>R{n+Ex+FnjYdP(;?jyvr^6i+>zUP;FTnQp zHsE7EDJ%4PJy{(Q`5(Y|W2g%V1Om`*w`HLDd>%G8H{t2&X~IU1PD~?UXJM1cN~!<5`+6FE3?)KA%rqsmYs_0pP+jlm!s@ZnrCC zhl`5~;YL}$wY3F>LIKE+{l^77JUqzY&(F_|1mk^{at}y1ZrN;>H=xme$^sIJ#Q4~c ztg2^cXGTMDKX2+A8U9xU4`qb#vG+JPs6#bKkEs@%44Z{$$*4Vd9QA=Vgrb@MZ)uNV8hqTl>38F1NUy=&dl8R|d zYmaI$YN={f(nin}oz_+*CSwd=Y$-bNGV?MI=bm%#Jumk@oWh_$9|d_Wc>n+ua9Ga} z31bf+D=n#^D^GkR1iBL9;{h~tk;{_CGd3I-7Z3m(m1tQ2bRz+fI@0H7$5*5 zVbH;h0seQ3WkCMZ2Sy6odldkrgg8(4lj)$9%HK`xf>rysQu<22qQ2!3`VGG28Gi}& zRVp%k=$b(ZQASZoGALENpUDx`u0fckFI5?TW+tlc=S3IppLZ}eS=@`&%xeJ`M|vBl zgbqn7k_jEqmlD+6lFQX7#fR?RCV~giP$(8OuQ+?s6c$2slyc;=^HlW^pumk5Cga10 z2z+X)m#(hv>+NmF;o;#q#!gttiLu@vGPAPuUCqtSr}$Gd$zrj1U`nvGv$K^W`1X~h9eB=Vhmt95sGH-$=7+9O)q*wi#N zDQIbH>pMB!X^q;Z99Bn%J_bWKH62V|c*@}OLnE1Vx(?RQ&nDE&$Vl4T+gr5R z_~!ll@*f@3F;1YGf$Hk&8PUhdNg|D=3NgIo;_NJL`e}Q3aj_P44u-&ki;9b36X^8b zwl**hhjTV0+1T5^y3}yExuxZJVq*RD5LmjQq>4EI`Lo>~yblJ0Q79CE$z)og(b10% znY%f}o~A>vqcXCfH(c((!a|G*?6_{zTkZlk7iFy1u1F=dDAzQ<&h5vWH@zVc)zsB{ z^71JQQnZQ+0h_qEv;_K^`RH~Pk%y_O?ds~9U0Bga{>|TFa5#SJo1538<`UM&keJef z26E-QPoGw%G)!V?sJh}VC@DyC%QKRpv0iqk3QqF(DED<^J<^%5Fk|=;#*U`=u76># z3$?D!xJG}D6d4|_u^Y5{iqhUNDHNJ!WMrf?gtdN`Q*9u+gT+dxsoB544#!`S7t(&zqjMXsm3vsQt9r*l2dEveK`&w->1spCih;W%O#JMMONCv>5D@u%t&8si@rt zQWTH6A>C4{GSBd@cI3`pf$d5CA?WPxHc(erXEm>tmYlUL*nXa!m?$rhzi@5Cu3fmi zoRX6xzd{hD5~xK*^7#XSFu}ORtc>{EgT~K7*|+XnTU!I=(TeG-&8h?!`N5pN@($vbDllJ}IrSh^w0-vy^)C zZ6By15D5RK!TR~l%~RWAT9jezO}P;cC;$F^15@epR0jtK>dC-x7NvO9Dx!_W@@BKy z{*kj{@rQPVX}0h@6benowg@bl;9@1rujfF5qRs2mNqLY%6I+I^GHD?YD4MnKO zCnj3AQ{ful1qBBy@%ogPeVNvQn*%BH&5s}Fve~{g#z9mF5b LE6}sq<6Pc9|F?f2 diff --git a/Telegram/Resources/icons/calls/voice_mute_mini.png b/Telegram/Resources/icons/calls/voice_mute_mini.png deleted file mode 100644 index 75615e4b000a2f0203a81f5133862ba8bc20c873..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 521 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1|%Pp+x`GjjKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uv49!D1}S`GTDlfwwx^3@hzIZ6 zkb|q597JTFy6VQbToB*Vy{(b^|6=|^&9%`ktL+y4f59H*GNHp>q2u(0x%0};FFDBU zu9_j7|G=uf_`L1(oqbVWnjSSdH|2}h_5PRs;#YB@Lv3>Bt@q!xJcVSBJpQ=j`X0d# zVx`AER=5O;+<04N)p7Fc)vG`AicfF)P+=p$a`5zo8FO-P>z})_rrhO{gJs|1MH)i= z&z027=lV&X+VS1YAdJtarjWUEV%F}vS`4dnPTPNe_U7ct+)GkfyTe}lTFCHqJdSvN z?)m0p>s~iG&YLqM%SU&k;w|CXXW2qS6L-cWZH!Rhake~DEI2v2Pb!P|*^}GSC#HAZ ze%to?YuC-3wu>1pU#r$O&yXp;5|I7L&@AC#)>fx!sUDX__Psy+*+%xrlNpPb9llf3 zv@FAJ{^JrW#q*!joTMfvue&(2Y_;EsYkQw;U!XU=TkPbDDQEWWUU2RoPf%w^+xOqG sr`u-*+x%d;^|SZ5_Q7d6l6xZ>_Z1Wkp00i_>zopr0L3-gKL7v# diff --git a/Telegram/Resources/icons/calls/voice_mute_mini@2x.png b/Telegram/Resources/icons/calls/voice_mute_mini@2x.png deleted file mode 100644 index 9eec8a1b38533808c1d10457a29f86364dcc544b..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1023 zcmVPx#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91FrWhf1ONa40RR91FaQ7m0NXcg3;+NFX-PyuRA>e5SiMeaK@eX4VnIl> zk%Y!*gBU6r42hA>+QK)mP@jQ>*)2jMDVWh^W#P_x-2CxQ+(w$}TMV+VXV9Hy(Q zs}bz?_xFUM6Kr5>F$p^f6bc1}^XBG;ve~Qx2_7;@u>GeJ2m}JuZnp)#*Vk7{r_;Xy zgbX?mY~f=m3GW@imXLIDap4FII!W{M^Nw~ViCH-o^wZ_;?vAfNnRMOU+}va%L#dSn z^fh^f^~Vu@nr_6<;K6zV25Va}^%JmCMh`*!4tOY@71#f-12Z!-tWv3n0e+k&$)t_0 z8xDs;{HJ)*ciL?9i@3SDDSu39YimpR@*gt#`1la=+uK{mc+i1h8;wSV9b!mAY!1|D z7;mBX_jgr{R4OHS4oKYp@vyYC#CCUgm5pQ|gARoEgO`^V!LO{Wh#4PxY$f~xW0Y|w zlaU3ZTCJvh*Voro7f|79wMrWs8)AT$9l{J-j!O*0kc8M$ZZMm*3>UY@$49Yduh&ys z0SlJPWr@XchK&S=ZG;#g#B}+dV3q(DKR!NI0E@+<0tDUm_BM4o9i^8HWY9_QnBgl4 zF?F2*Z=OIhnWVS3H?elV->22p)se;H@i^`5?9k!ip%~yH(?P)pz97UxOkHolnHJWwu|`!WF7!bcKf82}!)b(cUS5}~uRGl@aGZIwzTnw^~;UqC%W2OIfj z24}=TEVl^+J{|dFP8<-c*Xt~w&nsvAm2!G|%J@GJjK9zec_NWuYinzapGqtiiz(Yi zqrv#u&z_&3mCOy}I(xpDI63zB_eZL#+Ty^V1MqQq>Wt%cw}k*+AB&5NbaZq?Pft${ zuu14(16$qKBR>knV=xMZLgEX3a&n>)0go>(bYA0+`x{>+cz~&d>%jT>Icv3A$__ka zZm$X|&;-VM0&H7Lw4DgVB$MAHFS}daLP~WzNTq81c t^b;^Fn00f%1J+Aw7|`#4VZp4M{{pDH3w$NXWFY_m002ovPDHLkV1h^IwDkZ0 diff --git a/Telegram/Resources/icons/calls/voice_mute_mini@3x.png b/Telegram/Resources/icons/calls/voice_mute_mini@3x.png deleted file mode 100644 index 668b4a92b95b371fec9bef74cf000ccc2b89cd26..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1464 zcmah}dols0atPL9C*{Tq_Zo$e*TTK`7ULQiJHU#Z) zy6$vHqf50X(V}P6YsAq7t7j1EJ*|kxS#0NQf9{X(e&4Qw&i2Gyzlrw@!Qm%vp3P`4uBe8aDRmSaxY(S1#hHc80|Q~Jf$$D)I} z!JZCgrTJ0FXi1a=2@N1wLZO6_F?-L$5qIODP0~`U{PN#-=d;rLx%V@gUcC3b(D-WZ z$wF`M);@RDE4iOwl^6QXF#rp5Zx?d+17EAu+o?lY>OnaSW{N|XN<9|aCNQFcNU*y2 zF$f<(>V@)B)T0@OhwLN*rXv=jX1J6W85$dF79A5~g~#Ki3kz>A$`W;i6Ih8ZYJ72V zQMR(;OxCBus)|fr(K#AFibPzDkIxg{x}23C%*3Lgp^1qII-UNptVEz{A>)9NZ=DdC zTGe8)xH_8{5RgClL80I{Iy;w%MBW!#TU%>3x3<{R(+R#So15j~k&*1Jtt<*gmh-e3 z<>n@HxHmjZ=2TUExCzRbe5+=rrN{28ZeCtafltiLByvhi^yduT>^tdBFX0G zZEGEtmzKh9#)gNF$zBI$W(r6lh@xbBJ2W~h$S_wdCM7*&l@`A*EWh>=Kz(|6kHhIs z&>0*XGkYNvY7ucVUohWmc6N5X1H1DpP}UqzhKB^0_wWgXD{{_*JP_4JBo{?73{7Gf ze=m#{>uU^CSAhr`U{IC{NPR5gpM5v{!tCzu?rLvm4h_sBYi60kXL5yNn#iu*g)m)o zo;BRk)zJ~=pHw(nHc`^>k2W^aOMdIwpm%kJlgYxk_Ftq@*mMaAqwTjA-cOgqF#NkW`1b_rESi}foak5eZk579b>PqH8nG#`SrCt6FunX1|jFiyo=Ncsi~<^j&OSi( z>}+lUW{%2qrtzdA@KG-~xTfjB(RAacr-OrMFcH@-U!HZ?8Xb-4#<)P!2es-{&tU@3 ze!13WkT99#y7>_l9v0Toxwz@+;c*@GTp$n^7HZVe>NUIk@WIA{BtI?w+3G|(0B3b{ z_`~PeYy(bB%?k7-pI_G4(4fhm0<&^{uC}J}b&Hul?0yaZ@W$;OG&C#gxt=Q+jYhYs zy^mivfQwEp=bXDWHsvuz}&WOPQJP<~3TcniA+hBocih4DG=vRz)SU@tpkIJ@rdkyIYl0 zQxufDJ3#`qyg3oFl+U82rh1%@PD@L($Z2o)Ysa{==jM{jYHL>`6VOX$-lnFe@S&k0 z%C?8Cs<*0R=%`rix4N?O2itN>Ul4B~&~`-x+wIf@+uGR3dU{Uv0=}P}i0=W8H|nB+ z7n(+fh6C&C>%4FHL0uGW<*+X^wJiHo-q;rO@p5uU6@v*CYf4;~M?qnSTKiJBwWa diff --git a/Telegram/SourceFiles/calls/calls.style b/Telegram/SourceFiles/calls/calls.style index 79786255fd..c6149968c6 100644 --- a/Telegram/SourceFiles/calls/calls.style +++ b/Telegram/SourceFiles/calls/calls.style @@ -1132,49 +1132,55 @@ desktopCaptureSubmit: RoundButton(desktopCaptureCancel) { } groupCallNarrowSkip: 9px; -groupCallNarrowRowSkip: 4px; -groupCallNarrowSize: size(144px, 90px); -groupCallNarrowUserpicTop: 13px; -groupCallNarrowNameTop: 65px; -groupCallNarrowIconTop: 62px; -groupCallNarrowIconLess: 5px; -groupCallWideModeWidthMin: 550px; +groupCallNarrowMembersWidth: 202px; +//groupCallNarrowRowSkip: 4px; +//groupCallNarrowSize: size(144px, 90px); +//groupCallNarrowUserpicTop: 13px; +//groupCallNarrowNameTop: 65px; +//groupCallNarrowIconTop: 62px; +//groupCallNarrowIconLess: 5px; +groupCallWideModeWidthMin: 600px; groupCallWideModeSize: size(960px, 580px); -groupCallNarrowAddMemberHeight: 32px; -groupCallNarrowOutline: 2px; -groupCallNarrowShadowHeight: 36px; +//groupCallNarrowAddMemberHeight: 32px; +//groupCallNarrowOutline: 2px; +//groupCallNarrowShadowHeight: 36px; -groupCallNarrowAddMember: RoundButton(defaultActiveButton) { - textFg: groupCallMemberNotJoinedStatus; - textFgOver: groupCallMemberNotJoinedStatus; - textBg: groupCallMembersBg; - textBgOver: groupCallMembersBgOver; - - height: 32px; - radius: roundRadiusLarge; - - ripple: groupCallRipple; -} +//groupCallNarrowAddMember: RoundButton(defaultActiveButton) { +// textFg: groupCallMemberNotJoinedStatus; +// textFgOver: groupCallMemberNotJoinedStatus; +// textBg: groupCallMembersBg; +// textBgOver: groupCallMembersBgOver; +// +// height: 32px; +// radius: roundRadiusLarge; +// +// ripple: groupCallRipple; +//} groupCallNarrowInactiveCrossLine: CrossLineAnimation { - fg: groupCallMemberInactiveIcon; - icon: icon {{ "calls/voice_mute_mini", groupCallMemberInactiveIcon }}; - startPosition: point(7px, 4px); - endPosition: point(17px, 16px); + fg: groupCallMemberInactiveStatus; + icon: icon {{ "calls/video_mini_mute", groupCallMemberInactiveStatus }}; + startPosition: point(3px, 0px); + endPosition: point(13px, 12px); stroke: 3px; strokeDenominator: 2; } groupCallNarrowColoredCrossLine: CrossLineAnimation(groupCallNarrowInactiveCrossLine) { - fg: groupCallMemberMutedIcon; - icon: icon {{ "calls/voice_mute_mini", groupCallMemberActiveIcon }}; -} -groupCallVideoCrossLine: CrossLineAnimation(groupCallNarrowInactiveCrossLine) { - fg: groupCallVideoTextFg; - icon: icon {{ "calls/voice_mute_mini", groupCallVideoTextFg }}; + fg: groupCallMemberNotJoinedStatus; + icon: icon {{ "calls/video_mini_mute", groupCallMemberActiveStatus }}; } +groupCallNarrowRaisedHand: icon {{ "calls/video_mini_speak", groupCallMemberInactiveStatus }}; +groupCallNarrowCameraIcon: icon {{ "calls/video_mini_video", groupCallMemberInactiveStatus }}; +groupCallNarrowScreenIcon: icon {{ "calls/video_mini_screencast", groupCallMemberInactiveStatus }}; +groupCallNarrowIconPosition: point(-4px, 2px); +groupCallNarrowIconSkip: 15px; +//groupCallVideoCrossLine: CrossLineAnimation(groupCallNarrowInactiveCrossLine) { +// fg: groupCallVideoTextFg; +// icon: icon {{ "calls/voice_mute_mini", groupCallVideoTextFg }}; +//} groupCallLargeVideoCrossLine: CrossLineAnimation(groupCallMemberColoredCrossLine) { - fg: groupCallVideoSubTextFg; - icon: icon {{ "calls/group_calls_unmuted", groupCallVideoSubTextFg }}; + fg: groupCallVideoTextFg; + icon: icon {{ "calls/video_over_mute", groupCallVideoTextFg }}; } GroupCallLargeVideo { @@ -1196,16 +1202,16 @@ groupCallLargeVideoNarrow: GroupCallLargeVideo(groupCallLargeVideoWide) { enlargeAlign: align(center); pinPosition: point(-1px, -1px); } -groupCallLargeVideoListItem: PeerListItem(groupCallMembersListItem) { - nameFg: groupCallVideoTextFg; - nameFgChecked: groupCallVideoTextFg; - statusFg: groupCallVideoSubTextFg; - statusFgOver: groupCallVideoSubTextFg; - statusFgActive: groupCallVideoSubTextFg; -} +//groupCallLargeVideoListItem: PeerListItem(groupCallMembersListItem) { +// nameFg: groupCallVideoTextFg; +// nameFgChecked: groupCallVideoTextFg; +// statusFg: groupCallVideoSubTextFg; +// statusFgOver: groupCallVideoSubTextFg; +// statusFgActive: groupCallVideoSubTextFg; +//} groupCallLargeVideoPin: CrossLineAnimation { - fg: groupCallVideoSubTextFg; - icon: icon {{ "calls/voice_pin", groupCallVideoSubTextFg }}; + fg: groupCallVideoTextFg; + icon: icon {{ "calls/voice_pin", groupCallVideoTextFg }}; startPosition: point(5px, 2px); endPosition: point(20px, 17px); stroke: 2px; diff --git a/Telegram/SourceFiles/calls/group/calls_group_members.cpp b/Telegram/SourceFiles/calls/group/calls_group_members.cpp index 495400cdb8..05bd13b2a8 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_members.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_members.cpp @@ -82,6 +82,7 @@ public: -> rpl::producer>; Row *findRow(not_null participantPeer) const; + void setMode(PanelMode mode); bool rowIsMe(not_null participantPeer) override; bool rowCanMuteMembers() override; @@ -91,34 +92,41 @@ public: Painter &p, QRect rect, const IconState &state) override; - void rowPaintNarrowBackground( + int rowPaintStatusIcon( Painter &p, int x, int y, - bool selected) override; - void rowPaintNarrowBorder( - Painter &p, - int x, - int y, - not_null row) override; - void rowPaintNarrowShadow( - Painter &p, - int x, - int y, - int sizew, - int sizeh) override; + int outerWidth, + not_null row, + const IconState &state) override; + //void rowPaintNarrowBackground( + // Painter &p, + // int x, + // int y, + // bool selected) override; + //void rowPaintNarrowBorder( + // Painter &p, + // int x, + // int y, + // not_null row) override; + //void rowPaintNarrowShadow( + // Painter &p, + // int x, + // int y, + // int sizew, + // int sizeh) override; - int customRowHeight() override; - void customRowPaint( - Painter &p, - crl::time now, - not_null row, - bool selected) override; - bool customRowSelectionPoint( - not_null row, - int x, - int y) override; - Fn customRowRippleMaskGenerator() override; + //int customRowHeight() override; + //void customRowPaint( + // Painter &p, + // crl::time now, + // not_null row, + // bool selected) override; + //bool customRowSelectionPoint( + // not_null row, + // int x, + // int y) override; + //Fn customRowRippleMaskGenerator() override; private: [[nodiscard]] std::unique_ptr createRowForMe(); @@ -167,6 +175,10 @@ private: bool toggleRowVideo(not_null row); void showRowMenu(not_null row); + void toggleVideoEndpointActive( + const VideoEndpoint &endpoint, + bool active); + void appendInvitedUsers(); void scheduleRaisedHandStatusRemove(); @@ -188,17 +200,20 @@ private: base::Timer _raisedHandStatusRemoveTimer; base::flat_map> _soundingRowBySsrc; - base::flat_map> _videoEndpoints; + //base::flat_map> _videoEndpoints; + base::flat_set> _cameraActive; + base::flat_set> _screenActive; Ui::Animations::Basic _soundingAnimation; crl::time _soundingAnimationHideLastTime = 0; bool _skipRowLevelUpdate = false; + PanelMode _mode = PanelMode::Default; Ui::CrossLineAnimation _inactiveCrossLine; Ui::CrossLineAnimation _coloredCrossLine; Ui::CrossLineAnimation _inactiveNarrowCrossLine; Ui::CrossLineAnimation _coloredNarrowCrossLine; - Ui::CrossLineAnimation _videoNarrowCrossLine; + //Ui::CrossLineAnimation _videoNarrowCrossLine; Ui::CrossLineAnimation _videoLargeCrossLine; Ui::RoundRect _narrowRoundRectSelected; Ui::RoundRect _narrowRoundRect; @@ -219,7 +234,7 @@ Members::Controller::Controller( , _coloredCrossLine(st::groupCallMemberColoredCrossLine) , _inactiveNarrowCrossLine(st::groupCallNarrowInactiveCrossLine) , _coloredNarrowCrossLine(st::groupCallNarrowColoredCrossLine) -, _videoNarrowCrossLine(st::groupCallVideoCrossLine) +//, _videoNarrowCrossLine(st::groupCallVideoCrossLine) , _videoLargeCrossLine(st::groupCallLargeVideoCrossLine) , _narrowRoundRectSelected( ImageRoundRadius::Large, @@ -231,7 +246,7 @@ Members::Controller::Controller( _coloredCrossLine.invalidate(); _inactiveNarrowCrossLine.invalidate(); _coloredNarrowCrossLine.invalidate(); - _videoNarrowCrossLine.invalidate(); + //_videoNarrowCrossLine.invalidate(); }, _lifetime); rpl::combine( @@ -444,11 +459,64 @@ void Members::Controller::subscribeToChanges(not_null real) { } }, _lifetime); + for (const auto &[endpoint, track] : _call->activeVideoTracks()) { + toggleVideoEndpointActive(endpoint, true); + } + _call->videoStreamActiveUpdates( + ) | rpl::start_with_next([=](const VideoEndpoint &endpoint) { + const auto active = _call->activeVideoTracks().contains(endpoint); + toggleVideoEndpointActive(endpoint, active); + }, _lifetime); + if (_prepared) { appendInvitedUsers(); } } +void Members::Controller::toggleVideoEndpointActive( + const VideoEndpoint &endpoint, + bool active) { + const auto toggleOne = [=]( + base::flat_set> &set, + not_null participantPeer, + bool active) { + if ((active && set.emplace(participantPeer).second) + || (!active && set.remove(participantPeer))) { + if (_mode == PanelMode::Wide) { + if (const auto row = findRow(participantPeer)) { + delegate()->peerListUpdateRow(row); + } + } + } + }; + const auto &id = endpoint.id; + const auto participantPeer = endpoint.peer; + const auto real = _call->lookupReal(); + if (active) { + if (const auto participant = findParticipant(id)) { + if (computeCameraEndpoint(participant) == id) { + toggleOne(_cameraActive, participantPeer, true); + } else if (computeScreenEndpoint(participant) == id) { + toggleOne(_screenActive, participantPeer, true); + } + } + } else if (const auto participant = real->participantByPeer( + participantPeer)) { + const auto &camera = computeCameraEndpoint(participant); + const auto &screen = computeScreenEndpoint(participant); + if (camera == id || camera.empty()) { + toggleOne(_cameraActive, participantPeer, false); + } + if (screen == id || screen.empty()) { + toggleOne(_screenActive, participantPeer, false); + } + } else { + toggleOne(_cameraActive, participantPeer, false); + toggleOne(_screenActive, participantPeer, false); + } + +} + void Members::Controller::appendInvitedUsers() { if (const auto id = _call->id()) { for (const auto user : _peer->owner().invitedToCallUsers(id)) { @@ -714,6 +782,13 @@ Row *Members::Controller::findRow( delegate()->peerListFindRow(participantPeer->id.value)); } +void Members::Controller::setMode(PanelMode mode) { + if (_mode == mode) { + return; + } + _mode = mode; +} + const Data::GroupCallParticipant *Members::Controller::findParticipant( const std::string &endpoint) const { if (endpoint.empty()) { @@ -884,14 +959,28 @@ void Members::Controller::rowPaintIcon( Painter &p, QRect rect, const IconState &state) { - const auto narrowUserpic = (state.style == MembersRowStyle::Userpic); - const auto narrowVideo = (state.style == MembersRowStyle::Video); + if (_mode == PanelMode::Wide && state.style == MembersRowStyle::None) { + return; + } + //const auto narrowUserpic = (state.style == MembersRowStyle::Userpic); + //const auto narrowVideo = (state.style == MembersRowStyle::Video); + const auto narrow = (state.style == MembersRowStyle::Narrow); + if (!narrow && state.invited) { + st::groupCallMemberInvited.paintInCenter( + p, + QRect( + rect.topLeft() + st::groupCallMemberInvitedPosition, + st::groupCallMemberInvited.size())); + return; + } const auto largeVideo = (state.style == MembersRowStyle::LargeVideo); const auto &greenIcon = largeVideo ? st::groupCallLargeVideoCrossLine.icon - : narrowVideo - ? st::groupCallVideoCrossLine.icon - : narrowUserpic + //: narrowVideo + //? st::groupCallVideoCrossLine.icon + //: narrowUserpic + //? st::groupCallNarrowColoredCrossLine.icon + : narrow ? st::groupCallNarrowColoredCrossLine.icon : st::groupCallMemberColoredCrossLine.icon; const auto left = rect.x() + (rect.width() - greenIcon.width()) / 2; @@ -905,9 +994,11 @@ void Members::Controller::rowPaintIcon( // Just gray icon, no cross, no coloring. const auto &grayIcon = largeVideo ? st::groupCallLargeVideoCrossLine.icon - : narrowVideo - ? st::groupCallVideoCrossLine.icon - : narrowUserpic + //: narrowVideo + //? st::groupCallVideoCrossLine.icon + //: narrowUserpic + //? st::groupCallNarrowInactiveCrossLine.icon + : narrow ? st::groupCallNarrowInactiveCrossLine.icon : st::groupCallMemberInactiveCrossLine.icon; grayIcon.paintInCenter(p, rect); @@ -915,21 +1006,26 @@ void Members::Controller::rowPaintIcon( } else if (state.active == 0.) { if (state.muted == 1.) { if (state.raisedHand) { - // #TODO narrow mode icon - st::groupCallMemberRaisedHand.paintInCenter(p, rect); + (narrow + ? st::groupCallNarrowRaisedHand + : st::groupCallMemberRaisedHand).paintInCenter(p, rect); return; } // Red crossed icon, colorized once, cached as last frame. auto &line = largeVideo ? _videoLargeCrossLine - : narrowVideo - ? _videoNarrowCrossLine - : narrowUserpic + //: narrowVideo + //? _videoNarrowCrossLine + //: narrowUserpic + //? _coloredNarrowCrossLine + : narrow ? _coloredNarrowCrossLine : _coloredCrossLine; - const auto color = (largeVideo || narrowVideo) + const auto color = (largeVideo/* || narrowVideo*/) ? std::nullopt - : std::make_optional(st::groupCallMemberMutedIcon->c); + : std::make_optional(narrow + ? st::groupCallMemberNotJoinedStatus->c + : st::groupCallMemberMutedIcon->c); line.paint( p, left, @@ -941,9 +1037,11 @@ void Members::Controller::rowPaintIcon( // Gray crossed icon, no coloring, cached as last frame. auto &line = largeVideo ? _videoLargeCrossLine - : narrowVideo - ? _videoNarrowCrossLine - : narrowUserpic + //: narrowVideo + //? _videoNarrowCrossLine + //: narrowUserpic + //? _inactiveNarrowCrossLine + : narrow ? _inactiveNarrowCrossLine : _inactiveCrossLine; line.paint(p, left, top, 1.); @@ -952,119 +1050,163 @@ void Members::Controller::rowPaintIcon( } } const auto activeInactiveColor = anim::color( - st::groupCallMemberInactiveIcon, - (state.mutedByMe + (narrow + ? st::groupCallMemberInactiveStatus + : st::groupCallMemberInactiveIcon), + (narrow + ? st::groupCallMemberActiveStatus + : state.mutedByMe ? st::groupCallMemberMutedIcon : st::groupCallMemberActiveIcon), state.speaking); const auto iconColor = anim::color( activeInactiveColor, - st::groupCallMemberMutedIcon, + (narrow + ? st::groupCallMemberNotJoinedStatus + : st::groupCallMemberMutedIcon), state.muted); - const auto color = (largeVideo || narrowVideo) + const auto color = (largeVideo/* || narrowVideo*/) ? std::nullopt - : std::make_optional(iconColor); + : std::make_optional((narrow && state.mutedByMe) + ? st::groupCallMemberMutedIcon->c + : (narrow && state.raisedHand) + ? st::groupCallMemberInactiveStatus->c + : iconColor); // Don't use caching of the last frame, // because 'muted' may animate color. const auto crossProgress = std::min(1. - state.active, 0.9999); auto &line = largeVideo ? _videoLargeCrossLine - : narrowVideo - ? _videoNarrowCrossLine - : narrowUserpic + //: narrowVideo + //? _videoNarrowCrossLine + //: narrowUserpic + //? _inactiveNarrowCrossLine + : narrow ? _inactiveNarrowCrossLine : _inactiveCrossLine; line.paint(p, left, top, crossProgress, color); } -void Members::Controller::rowPaintNarrowBackground( +int Members::Controller::rowPaintStatusIcon( Painter &p, int x, int y, - bool selected) { - (selected ? _narrowRoundRectSelected : _narrowRoundRect).paint( - p, - { QPoint(x, y), st::groupCallNarrowSize }); -} + int outerWidth, + not_null row, + const IconState &state) { + Expects(state.style == MembersRowStyle::Narrow); -void Members::Controller::rowPaintNarrowBorder( - Painter &p, - int x, - int y, - not_null row) { - //if (_call->videoEndpointLarge().peer != row->peer().get()) { - // return; - //} - //auto hq = PainterHighQualityEnabler(p); - //p.setBrush(Qt::NoBrush); - //auto pen = st::groupCallMemberActiveIcon->p; - //pen.setWidthF(st::groupCallNarrowOutline); - //p.setPen(pen); - //p.drawRoundedRect( - // QRect{ QPoint(x, y), st::groupCallNarrowSize }, - // st::roundRadiusLarge, - // st::roundRadiusLarge); -} - -void Members::Controller::rowPaintNarrowShadow( - Painter &p, - int x, - int y, - int sizew, - int sizeh) { - if (_narrowShadow.isNull()) { - _narrowShadow = GenerateShadow( - st::groupCallNarrowShadowHeight, - 0, - kShadowMaxAlpha); + if (_mode != PanelMode::Wide) { + return 0; } - const auto height = st::groupCallNarrowShadowHeight; - p.drawImage( - QRect(x, y + sizeh - height, sizew, height), - _narrowShadow); + const auto &icon = st::groupCallNarrowColoredCrossLine.icon; + x += st::groupCallNarrowIconPosition.x(); + y += st::groupCallNarrowIconPosition.y(); + const auto rect = QRect(x, y, icon.width(), icon.height()); + rowPaintIcon(p, rect, state); + x += icon.width(); + auto result = st::groupCallNarrowIconSkip; + if (_cameraActive.contains(row->peer())) { + st::groupCallNarrowCameraIcon.paint(p, x, y, outerWidth); + x += st::groupCallNarrowCameraIcon.width(); + result += st::groupCallNarrowCameraIcon.width(); + } + if (_screenActive.contains(row->peer())) { + st::groupCallNarrowScreenIcon.paint(p, x, y, outerWidth); + x += st::groupCallNarrowScreenIcon.width(); + result += st::groupCallNarrowScreenIcon.width(); + } + return result; } -int Members::Controller::customRowHeight() { - return st::groupCallNarrowSize.height() + st::groupCallNarrowRowSkip * 2; -} - -void Members::Controller::customRowPaint( - Painter &p, - crl::time now, - not_null row, - bool selected) { - const auto real = static_cast(row.get()); - const auto width = st::groupCallNarrowSize.width(); - const auto height = st::groupCallNarrowSize.height(); - real->paintComplexUserpic( - p, - st::groupCallNarrowSkip, - st::groupCallNarrowRowSkip, - width, - width, - height, - PanelMode::Wide, - selected); -} - -bool Members::Controller::customRowSelectionPoint( - not_null row, - int x, - int y) { - return x >= st::groupCallNarrowSkip - && x < st::groupCallNarrowSkip + st::groupCallNarrowSize.width() - && y >= st::groupCallNarrowRowSkip - && y < st::groupCallNarrowRowSkip + st::groupCallNarrowSize.height(); -} - -Fn Members::Controller::customRowRippleMaskGenerator() { - return [] { - return Ui::RippleAnimation::roundRectMask( - st::groupCallNarrowSize, - st::roundRadiusLarge); - }; -} +//void Members::Controller::rowPaintNarrowBackground( +// Painter &p, +// int x, +// int y, +// bool selected) { +// (selected ? _narrowRoundRectSelected : _narrowRoundRect).paint( +// p, +// { QPoint(x, y), st::groupCallNarrowSize }); +//} +// +//void Members::Controller::rowPaintNarrowBorder( +// Painter &p, +// int x, +// int y, +// not_null row) { +// if (_call->videoEndpointLarge().peer != row->peer().get()) { +// return; +// } +// auto hq = PainterHighQualityEnabler(p); +// p.setBrush(Qt::NoBrush); +// auto pen = st::groupCallMemberActiveIcon->p; +// pen.setWidthF(st::groupCallNarrowOutline); +// p.setPen(pen); +// p.drawRoundedRect( +// QRect{ QPoint(x, y), st::groupCallNarrowSize }, +// st::roundRadiusLarge, +// st::roundRadiusLarge); +//} +// +//void Members::Controller::rowPaintNarrowShadow( +// Painter &p, +// int x, +// int y, +// int sizew, +// int sizeh) { +// if (_narrowShadow.isNull()) { +// _narrowShadow = GenerateShadow( +// st::groupCallNarrowShadowHeight, +// 0, +// kShadowMaxAlpha); +// } +// const auto height = st::groupCallNarrowShadowHeight; +// p.drawImage( +// QRect(x, y + sizeh - height, sizew, height), +// _narrowShadow); +//} +// +//int Members::Controller::customRowHeight() { +// return st::groupCallNarrowSize.height() + st::groupCallNarrowRowSkip * 2; +//} +// +//void Members::Controller::customRowPaint( +// Painter &p, +// crl::time now, +// not_null row, +// bool selected) { +// const auto real = static_cast(row.get()); +// const auto width = st::groupCallNarrowSize.width(); +// const auto height = st::groupCallNarrowSize.height(); +// real->paintComplexUserpic( +// p, +// st::groupCallNarrowSkip, +// st::groupCallNarrowRowSkip, +// width, +// width, +// height, +// PanelMode::Wide, +// selected); +//} +// +//bool Members::Controller::customRowSelectionPoint( +// not_null row, +// int x, +// int y) { +// return x >= st::groupCallNarrowSkip +// && x < st::groupCallNarrowSkip + st::groupCallNarrowSize.width() +// && y >= st::groupCallNarrowRowSkip +// && y < st::groupCallNarrowRowSkip + st::groupCallNarrowSize.height(); +//} +// +//Fn Members::Controller::customRowRippleMaskGenerator() { +// return [] { +// return Ui::RippleAnimation::roundRectMask( +// st::groupCallNarrowSize, +// st::roundRadiusLarge); +// }; +//} auto Members::Controller::kickParticipantRequests() const -> rpl::producer>{ @@ -1507,9 +1649,9 @@ int Members::desiredHeight() const { return 0; }(); const auto use = std::max(count, _list->fullRowsCount()); - const auto single = (_mode.current() == PanelMode::Wide) + const auto single = /*(_mode.current() == PanelMode::Wide) ? (st::groupCallNarrowSize.height() + st::groupCallNarrowRowSkip * 2) - : st::groupCallMembersList.item.height; + : */st::groupCallMembersList.item.height; return top + (use * single) + (use ? st::lineWidth : 0); @@ -1563,9 +1705,9 @@ void Members::setupAddMember(not_null call) { } auto addMember = (Ui::AbstractButton*)nullptr; auto wrap = [&]() -> object_ptr { - if (mode == PanelMode::Default) { + //if (mode == PanelMode::Default) { auto result = Settings::CreateButton( - this, + _layout.get(), tr::lng_group_call_invite(), st::groupCallAddMember, &st::groupCallAddMemberIcon, @@ -1573,34 +1715,36 @@ void Members::setupAddMember(not_null call) { &st::groupCallMemberInactiveIcon); addMember = result.data(); return result; - } - auto result = object_ptr(_layout.get()); - const auto skip = st::groupCallNarrowSkip; - const auto fullwidth = st::groupCallNarrowSize.width() - + 2 * skip; - const auto fullheight = st::groupCallNarrowAddMember.height - + st::groupCallNarrowRowSkip; - result->resize(fullwidth, fullheight); - const auto button = Ui::CreateChild( - result.data(), - rpl::single(QString()), - st::groupCallNarrowAddMember); - button->move(skip, 0); - const auto width = fullwidth - 2 * skip; - button->setFullWidth(width); - Settings::AddButtonIcon( - button, - &st::groupCallAddMemberIcon, - (width - st::groupCallAddMemberIcon.width()) / 2, - &st::groupCallMemberInactiveIcon); - addMember = button; - return result; + //} + //auto result = object_ptr(_layout.get()); + //const auto skip = st::groupCallNarrowSkip; + //const auto fullwidth = st::groupCallNarrowSize.width() + // + 2 * skip; + //const auto fullheight = st::groupCallNarrowAddMember.height + // + st::groupCallNarrowRowSkip; + //result->resize(fullwidth, fullheight); + //const auto button = Ui::CreateChild( + // result.data(), + // rpl::single(QString()), + // st::groupCallNarrowAddMember); + //button->move(skip, 0); + //const auto width = fullwidth - 2 * skip; + //button->setFullWidth(width); + //Settings::AddButtonIcon( + // button, + // &st::groupCallAddMemberIcon, + // (width - st::groupCallAddMemberIcon.width()) / 2, + // &st::groupCallMemberInactiveIcon); + //addMember = button; + //return result; }(); addMember->show(); addMember->clicks( ) | rpl::to_empty | rpl::start_to_stream( _addMemberRequests, addMember->lifetime()); + wrap->show(); + wrap->resizeToWidth(_layout->width()); _addMemberButton = wrap.data(); _layout->insert(1, std::move(wrap)); }, lifetime()); @@ -1622,9 +1766,10 @@ void Members::setMode(PanelMode mode) { for (const auto &tile : _videoTiles) { tile.video->setVisible(mode == PanelMode::Default); } - _list->setMode((mode == PanelMode::Wide) - ? PeerListContent::Mode::Custom - : PeerListContent::Mode::Default); + _listController->setMode(mode); + //_list->setMode((mode == PanelMode::Wide) + // ? PeerListContent::Mode::Custom + // : PeerListContent::Mode::Default); } rpl::producer Members::fullCountValue() const { @@ -1763,15 +1908,26 @@ void Members::setupPinnedVideo() { } _call->videoStreamActiveUpdates( ) | rpl::start_with_next([=](const VideoEndpoint &endpoint) { - const auto &tracks = _call->activeVideoTracks(); - const auto i = tracks.find(endpoint); - if (i != end(tracks)) { - _videoTiles.push_back(setupTile(endpoint, i->second)); + if (_call->activeVideoTracks().contains(endpoint)) { + // Add async (=> the participant row is definitely in Members). + crl::on_main(_pinnedVideoWrap, [=] { + const auto &tracks = _call->activeVideoTracks(); + const auto i = tracks.find(endpoint); + if (i != end(tracks)) { + _videoTiles.push_back(setupTile(endpoint, i->second)); + } + }); } else { - _videoTiles.erase( - ranges::remove(_videoTiles, endpoint, &VideoTile::endpoint), - end(_videoTiles)); - refreshTilesGeometry(); + // Remove sync. + const auto eraseTill = end(_videoTiles); + const auto eraseFrom = ranges::remove( + _videoTiles, + endpoint, + &VideoTile::endpoint); + if (eraseFrom != eraseTill) { + _videoTiles.erase(eraseFrom, eraseTill); + refreshTilesGeometry(); + } } }, _pinnedVideoWrap->lifetime()); diff --git a/Telegram/SourceFiles/calls/group/calls_group_members_row.cpp b/Telegram/SourceFiles/calls/group/calls_group_members_row.cpp index fc074885c0..d87fcb398c 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_members_row.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_members_row.cpp @@ -412,15 +412,15 @@ bool MembersRow::paintVideo( //return true; } -std::tuple MembersRow::UserpicInNarrowMode( - int x, - int y, - int sizew, - int sizeh) { - const auto useSize = st::groupCallMembersList.item.photoSize; - const auto skipx = (sizew - useSize) / 2; - return { x + skipx, y + st::groupCallNarrowUserpicTop, useSize }; -} +//std::tuple MembersRow::UserpicInNarrowMode( +// int x, +// int y, +// int sizew, +// int sizeh) { +// const auto useSize = st::groupCallMembersList.item.photoSize; +// const auto skipx = (sizew - useSize) / 2; +// return { x + skipx, y + st::groupCallNarrowUserpicTop, useSize }; +//} void MembersRow::paintBlobs( Painter &p, @@ -433,9 +433,9 @@ void MembersRow::paintBlobs( return; } auto size = sizew; - if (mode == PanelMode::Wide) { - std::tie(x, y, size) = UserpicInNarrowMode(x, y, sizew, sizeh); - } + //if (mode == PanelMode::Wide) { + // std::tie(x, y, size) = UserpicInNarrowMode(x, y, sizew, sizeh); + //} const auto mutedByMe = (_state == State::MutedByMe); const auto shift = QPointF(x + size / 2., y + size / 2.); auto hq = PainterHighQualityEnabler(p); @@ -461,9 +461,9 @@ void MembersRow::paintScaledUserpic( int sizeh, PanelMode mode) { auto size = sizew; - if (mode == PanelMode::Wide) { - std::tie(x, y, size) = UserpicInNarrowMode(x, y, sizew, sizeh); - } + //if (mode == PanelMode::Wide) { + // std::tie(x, y, size) = UserpicInNarrowMode(x, y, sizew, sizeh); + //} if (!_blobsAnimation) { peer()->paintUserpicLeft(p, userpic, x, y, outerWidth, size); return; @@ -503,72 +503,72 @@ void MembersRow::paintMuteIcon( _delegate->rowPaintIcon(p, iconRect, computeIconState(style)); } -void MembersRow::paintNarrowName( - Painter &p, - int x, - int y, - int sizew, - int sizeh, - MembersRowStyle style) { - if (_narrowName.isEmpty()) { - _narrowName.setText( - st::semiboldTextStyle, - generateShortName(), - Ui::NameTextOptions()); - } - if (style == MembersRowStyle::Video) { - _delegate->rowPaintNarrowShadow(p, x, y, sizew, sizeh); - } - const auto &icon = st::groupCallVideoCrossLine.icon; - const auto added = icon.width() - st::groupCallNarrowIconLess; - const auto available = sizew - 2 * st::normalFont->spacew - added; - const auto use = std::min(available, _narrowName.maxWidth()); - const auto left = x + (sizew - use - added) / 2; - const auto iconRect = QRect( - left - st::groupCallNarrowIconLess, - y + st::groupCallNarrowIconTop, - icon.width(), - icon.height()); - const auto &state = computeIconState(style); - _delegate->rowPaintIcon(p, iconRect, state); - - p.setPen([&] { - if (style == MembersRowStyle::Video) { - return st::groupCallVideoTextFg->p; - } else if (state.speaking == 1. && !state.mutedByMe) { - return st::groupCallMemberActiveIcon->p; - } else if (state.speaking == 0.) { - if (state.active == 1.) { - return st::groupCallMemberInactiveIcon->p; - } else if (state.active == 0.) { - if (state.muted == 1.) { - return state.raisedHand - ? st::groupCallMemberInactiveStatus->p - : st::groupCallMemberMutedIcon->p; - } else if (state.muted == 0.) { - return st::groupCallMemberInactiveIcon->p; - } - } - } - const auto activeInactiveColor = anim::color( - st::groupCallMemberInactiveIcon, - (state.mutedByMe - ? st::groupCallMemberMutedIcon - : st::groupCallMemberActiveIcon), - state.speaking); - return anim::pen( - activeInactiveColor, - st::groupCallMemberMutedIcon, - state.muted); - }()); - const auto nameLeft = iconRect.x() + icon.width(); - const auto nameTop = y + st::groupCallNarrowNameTop; - if (use == available) { - _narrowName.drawLeftElided(p, nameLeft, nameTop, available, sizew); - } else { - _narrowName.drawLeft(p, nameLeft, nameTop, available, sizew); - } -} +//void MembersRow::paintNarrowName( +// Painter &p, +// int x, +// int y, +// int sizew, +// int sizeh, +// MembersRowStyle style) { +// if (_narrowName.isEmpty()) { +// _narrowName.setText( +// st::semiboldTextStyle, +// generateShortName(), +// Ui::NameTextOptions()); +// } +// if (style == MembersRowStyle::Video) { +// _delegate->rowPaintNarrowShadow(p, x, y, sizew, sizeh); +// } +// const auto &icon = st::groupCallVideoCrossLine.icon; +// const auto added = icon.width() - st::groupCallNarrowIconLess; +// const auto available = sizew - 2 * st::normalFont->spacew - added; +// const auto use = std::min(available, _narrowName.maxWidth()); +// const auto left = x + (sizew - use - added) / 2; +// const auto iconRect = QRect( +// left - st::groupCallNarrowIconLess, +// y + st::groupCallNarrowIconTop, +// icon.width(), +// icon.height()); +// const auto &state = computeIconState(style); +// _delegate->rowPaintIcon(p, iconRect, state); +// +// p.setPen([&] { +// if (style == MembersRowStyle::Video) { +// return st::groupCallVideoTextFg->p; +// } else if (state.speaking == 1. && !state.mutedByMe) { +// return st::groupCallMemberActiveIcon->p; +// } else if (state.speaking == 0.) { +// if (state.active == 1.) { +// return st::groupCallMemberInactiveIcon->p; +// } else if (state.active == 0.) { +// if (state.muted == 1.) { +// return state.raisedHand +// ? st::groupCallMemberInactiveStatus->p +// : st::groupCallMemberMutedIcon->p; +// } else if (state.muted == 0.) { +// return st::groupCallMemberInactiveIcon->p; +// } +// } +// } +// const auto activeInactiveColor = anim::color( +// st::groupCallMemberInactiveIcon, +// (state.mutedByMe +// ? st::groupCallMemberMutedIcon +// : st::groupCallMemberActiveIcon), +// state.speaking); +// return anim::pen( +// activeInactiveColor, +// st::groupCallMemberMutedIcon, +// state.muted); +// }()); +// const auto nameLeft = iconRect.x() + icon.width(); +// const auto nameTop = y + st::groupCallNarrowNameTop; +// if (use == available) { +// _narrowName.drawLeftElided(p, nameLeft, nameTop, available, sizew); +// } else { +// _narrowName.drawLeft(p, nameLeft, nameTop, available, sizew); +// } +//} auto MembersRow::generatePaintUserpicCallback() -> PaintRoundImageCallback { return [=](Painter &p, int x, int y, int outerWidth, int size) { @@ -586,20 +586,20 @@ void MembersRow::paintComplexUserpic( int sizeh, PanelMode mode, bool selected) { - if (mode == PanelMode::Wide) { - if (paintVideo(p, x, y, sizew, sizeh, mode)) { - paintNarrowName(p, x, y, sizew, sizeh, MembersRowStyle::Video); - _delegate->rowPaintNarrowBorder(p, x, y, this); - return; - } - _delegate->rowPaintNarrowBackground(p, x, y, selected); - paintRipple(p, x, y, outerWidth); - } + //if (mode == PanelMode::Wide) { + // if (paintVideo(p, x, y, sizew, sizeh, mode)) { + // paintNarrowName(p, x, y, sizew, sizeh, MembersRowStyle::Video); + // _delegate->rowPaintNarrowBorder(p, x, y, this); + // return; + // } + // _delegate->rowPaintNarrowBackground(p, x, y, selected); + // paintRipple(p, x, y, outerWidth); + //} paintBlobs(p, x, y, sizew, sizeh, mode); - if (mode == PanelMode::Default - && paintVideo(p, x, y, sizew, sizeh, mode)) { - return; - } + //if (mode == PanelMode::Default + // && paintVideo(p, x, y, sizew, sizeh, mode)) { + // return; + //} paintScaledUserpic( p, ensureUserpicView(), @@ -609,20 +609,22 @@ void MembersRow::paintComplexUserpic( sizew, sizeh, mode); - if (mode == PanelMode::Wide) { - paintNarrowName(p, x, y, sizew, sizeh, MembersRowStyle::Userpic); - _delegate->rowPaintNarrowBorder(p, x, y, this); - } + //if (mode == PanelMode::Wide) { + // paintNarrowName(p, x, y, sizew, sizeh, MembersRowStyle::Userpic); + // _delegate->rowPaintNarrowBorder(p, x, y, this); + //} } -int MembersRow::statusIconWidth() const { +int MembersRow::statusIconWidth(bool skipIcon) const { if (!_statusIcon || !_speaking) { return 0; } const auto shown = _statusIcon->shownAnimation.value( _statusIcon->shown ? 1. : 0.); - const auto full = _statusIcon->speaker.width() - + _statusIcon->arcsWidth + const auto iconWidth = skipIcon + ? 0 + : (_statusIcon->speaker.width() + _statusIcon->arcsWidth); + const auto full = iconWidth + _statusIcon->percentWidth + st::normalFont->spacew; return int(std::round(shown * full)); @@ -638,7 +640,8 @@ void MembersRow::paintStatusIcon( int y, const style::PeerListItem &st, const style::font &font, - bool selected) { + bool selected, + bool skipIcon) { if (!_statusIcon) { return; } @@ -661,8 +664,10 @@ void MembersRow::paintStatusIcon( + QPoint( speakerRect.width() - st::groupCallStatusSpeakerArcsSkip, speakerRect.height() / 2); - const auto fullWidth = speakerRect.width() - + _statusIcon->arcsWidth + const auto iconWidth = skipIcon + ? 0 + : (speakerRect.width() + _statusIcon->arcsWidth); + const auto fullWidth = iconWidth + _statusIcon->percentWidth + st::normalFont->spacew; @@ -674,18 +679,20 @@ void MembersRow::paintStatusIcon( p.scale(shown, shown); p.translate(-centerx, -centery); } - _statusIcon->speaker.paint( - p, - speakerRect.topLeft(), - speakerRect.width(), - color); - p.translate(arcPosition); - _statusIcon->arcs.paint(p, color); - p.translate(-arcPosition); + if (!skipIcon) { + _statusIcon->speaker.paint( + p, + speakerRect.topLeft(), + speakerRect.width(), + color); + p.translate(arcPosition); + _statusIcon->arcs.paint(p, color); + p.translate(-arcPosition); + } p.setFont(st::normalFont); p.setPen(st.statusFgActive); p.drawTextLeft( - x + speakerRect.width() + _statusIcon->arcsWidth, + x + iconWidth, y, fullWidth, _statusIcon->percent); @@ -728,20 +735,31 @@ void MembersRow::paintComplexStatusText( int outerWidth, bool selected, MembersRowStyle style) { + const auto skip = (style == MembersRowStyle::None) + ? _delegate->rowPaintStatusIcon( + p, + x, + y, + outerWidth, + this, + computeIconState(MembersRowStyle::Narrow)) + : 0; + const auto narrowMode = (skip > 0); + x += skip; + availableWidth -= skip; const auto &font = st::normalFont; const auto about = (style == MembersRowStyle::LargeVideo) ? QString() - : (_state == State::Inactive - || _state == State::Muted - || (_state == State::RaisedHand && !_raisedHandStatus)) + : ((_state == State::RaisedHand && !_raisedHandStatus) + || (_state != State::Active && _state != State::RaisedHand)) ? _aboutText : QString(); if (about.isEmpty() && _state != State::Invited && _state != State::MutedByMe) { - paintStatusIcon(p, x, y, st, font, selected); + paintStatusIcon(p, x, y, st, font, selected, narrowMode); - const auto translatedWidth = statusIconWidth(); + const auto translatedWidth = statusIconWidth(narrowMode); p.translate(translatedWidth, 0); const auto guard = gsl::finally([&] { p.translate(-translatedWidth, 0); @@ -762,6 +780,8 @@ void MembersRow::paintComplexStatusText( p.setPen(st::groupCallVideoSubTextFg); } else if (_state == State::MutedByMe) { p.setPen(st::groupCallMemberMutedIcon); + } else if (narrowMode && !about.isEmpty()) { + p.setPen(st::groupCallMembersFg); } else { p.setPen(st::groupCallMemberNotJoinedStatus); } @@ -814,11 +834,6 @@ void MembersRow::paintAction( outerWidth); if (_state == State::Invited) { _actionRipple = nullptr; - st::groupCallMemberInvited.paint( - p, - QPoint(x, y) + st::groupCallMemberInvitedPosition, - outerWidth); - return; } if (_actionRipple) { _actionRipple->paint( @@ -847,6 +862,7 @@ MembersRowDelegate::IconState MembersRow::computeIconState( .muted = muted, .mutedByMe = (_state == State::MutedByMe), .raisedHand = (_state == State::RaisedHand), + .invited = (_state == State::Invited), .style = style, }; } @@ -911,7 +927,7 @@ void MembersRow::addActionRipple(QPoint point, Fn updateCallback) { void MembersRow::refreshName(const style::PeerListItem &st) { PeerListRow::refreshName(st); - _narrowName = Ui::Text::String(); + //_narrowName = Ui::Text::String(); } void MembersRow::stopLastActionRipple() { diff --git a/Telegram/SourceFiles/calls/group/calls_group_members_row.h b/Telegram/SourceFiles/calls/group/calls_group_members_row.h index 677182bf9a..54b6afa0df 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_members_row.h +++ b/Telegram/SourceFiles/calls/group/calls_group_members_row.h @@ -29,8 +29,9 @@ namespace Calls::Group { enum class MembersRowStyle { None, - Userpic, - Video, + //Userpic, + //Video, + Narrow, LargeVideo, }; @@ -43,6 +44,7 @@ public: float64 muted = 0.; bool mutedByMe = false; bool raisedHand = false; + bool invited = false; MembersRowStyle style = MembersRowStyle::None; }; virtual bool rowIsMe(not_null participantPeer) = 0; @@ -53,22 +55,29 @@ public: Painter &p, QRect rect, const IconState &state) = 0; - virtual void rowPaintNarrowBackground( + virtual int rowPaintStatusIcon( Painter &p, int x, int y, - bool selected) = 0; - virtual void rowPaintNarrowBorder( - Painter &p, - int x, - int y, - not_null row) = 0; - virtual void rowPaintNarrowShadow( - Painter &p, - int x, - int y, - int sizew, - int sizeh) = 0; + int outerWidth, + not_null row, + const IconState &state) = 0; + //virtual void rowPaintNarrowBackground( + // Painter &p, + // int x, + // int y, + // bool selected) = 0; + //virtual void rowPaintNarrowBorder( + // Painter &p, + // int x, + // int y, + // not_null row) = 0; + //virtual void rowPaintNarrowShadow( + // Painter &p, + // int x, + // int y, + // int sizew, + // int sizeh) = 0; }; class MembersRow final : public PeerListRow { @@ -174,7 +183,7 @@ private: struct BlobsAnimation; struct StatusIcon; - int statusIconWidth() const; + int statusIconWidth(bool skipIcon) const; int statusIconHeight() const; void paintStatusIcon( Painter &p, @@ -182,7 +191,8 @@ private: int y, const style::PeerListItem &st, const style::font &font, - bool selected); + bool selected, + bool skipIcon); void refreshStatus() override; void setSounding(bool sounding); @@ -201,11 +211,11 @@ private: int sizew, int sizeh, PanelMode mode); - [[nodiscard]] static std::tuple UserpicInNarrowMode( - int x, - int y, - int sizew, - int sizeh); + //[[nodiscard]] static std::tuple UserpicInNarrowMode( + // int x, + // int y, + // int sizew, + // int sizeh); void paintBlobs( Painter &p, int x, diff --git a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp index 34f1fb9679..e356dc54d7 100644 --- a/Telegram/SourceFiles/calls/group/calls_group_panel.cpp +++ b/Telegram/SourceFiles/calls/group/calls_group_panel.cpp @@ -1923,7 +1923,7 @@ void Panel::updateButtonsGeometry() { + (_settings ? _settings : _callShare)->width() + skip + _hangup->width() + skip; const auto membersSkip = st::groupCallNarrowSkip; - const auto membersWidth = st::groupCallNarrowSize.width() + const auto membersWidth = st::groupCallNarrowMembersWidth + 2 * membersSkip; auto left = (_mode == PanelMode::Default) ? (widget()->width() - fullWidth) / 2 @@ -1998,17 +1998,17 @@ void Panel::updateMembersGeometry() { const auto desiredHeight = _members->desiredHeight(); if (_mode == PanelMode::Wide) { const auto skip = st::groupCallNarrowSkip; - const auto membersWidth = st::groupCallNarrowSize.width() + 2 * skip; + const auto membersWidth = st::groupCallNarrowMembersWidth; const auto top = st::groupCallWideVideoTop; _members->setGeometry( - 0, + skip, top, membersWidth, std::min(desiredHeight, widget()->height())); _pinnedVideoWrap->setGeometry( - membersWidth, + membersWidth + 2 * skip, top, - widget()->width() - membersWidth - skip, + widget()->width() - membersWidth - 3 * skip, widget()->height() - top - skip); } else { const auto membersBottom = _videoMode.current()