From ed4dea2b0e7ed67535fddd4c6264a0c787f6ae47 Mon Sep 17 00:00:00 2001 From: John Preston Date: Fri, 12 Mar 2021 21:51:39 +0400 Subject: [PATCH] Show and play 'allowed to speak' notification. --- Telegram/Resources/langs/lang.strings | 2 +- Telegram/Resources/qrc/telegram/sounds.qrc | 1 + .../Resources/sounds/group_call_allowed.mp3 | Bin 0 -> 15744 bytes .../SourceFiles/calls/calls_group_call.cpp | 65 ++++++++++++------ Telegram/SourceFiles/calls/calls_group_call.h | 18 ++++- .../SourceFiles/calls/calls_group_panel.cpp | 39 +++++++++-- Telegram/SourceFiles/calls/calls_instance.cpp | 1 + Telegram/SourceFiles/calls/calls_top_bar.cpp | 38 +++++++--- 8 files changed, 124 insertions(+), 40 deletions(-) create mode 100644 Telegram/Resources/sounds/group_call_allowed.mp3 diff --git a/Telegram/Resources/langs/lang.strings b/Telegram/Resources/langs/lang.strings index b74b24256..a53623bee 100644 --- a/Telegram/Resources/langs/lang.strings +++ b/Telegram/Resources/langs/lang.strings @@ -2002,7 +2002,7 @@ https://github.com/telegramdesktop/tdesktop/blob/master/LEGAL "lng_group_call_recording_stop" = "Stop recording"; "lng_group_call_recording_started" = "Voice chat recording started."; "lng_group_call_recording_stopped" = "Voice chat recording stopped."; -"lng_group_call_recording_saved" = "Audio saved to Saved Messages"; +"lng_group_call_recording_saved" = "Audio saved to Saved Messages."; "lng_group_call_recording_start_sure" = "Do you want to start recording this chat and save the result into an audio file?\n\nOther members will see the chat is being recorded."; "lng_group_call_recording_stop_sure" = "Do you want to stop recording this chat?"; "lng_group_call_recording_start_field" = "Recording Title"; diff --git a/Telegram/Resources/qrc/telegram/sounds.qrc b/Telegram/Resources/qrc/telegram/sounds.qrc index 69d1427e5..d9f7cf8b5 100644 --- a/Telegram/Resources/qrc/telegram/sounds.qrc +++ b/Telegram/Resources/qrc/telegram/sounds.qrc @@ -9,5 +9,6 @@ ../../sounds/group_call_start.mp3 ../../sounds/group_call_connect.mp3 ../../sounds/group_call_end.mp3 + ../../sounds/group_call_allowed.mp3 diff --git a/Telegram/Resources/sounds/group_call_allowed.mp3 b/Telegram/Resources/sounds/group_call_allowed.mp3 new file mode 100644 index 0000000000000000000000000000000000000000..b5dfaa606c912db5c22a97611a8a5755bbc1a702 GIT binary patch literal 15744 zcmdVBWn7d&_dk5?vNXbyQqtY62FAtj-dAYA`N z@B8!ny?XvHo;S}kpN(sGXTIlq&YU@Cu9;czDgg%kUy8nis~xHe0qV&G01`+53yYAD zo}Pz?M@&pfNmtk0+}y#z!{hbqkdTm=nB?TFtgQU}va;&x#>U1^pSruhd>I}do|u@K zSy)(DT3T6ITie*!*xK6O-rqkuIyyf7_3Py1e}geV2wZ$P z^MZP^S1R-CV#$>OAj*Kz1@Z>m`2CefJsnG#@G-In>h_SIE|Z1qh1H)&bXdU|;a_;^ zd0z6V627v^uxbYj!AX=!s2^v+Xu)D@eA-F3jY(L(xmWsQ^>3fB)>kb`rPaV)NLv+M zdMF5jH-}&+q-^F@+kEeUQWo%iIo|v}t0im}vq6F==BFP=p3e`C$-9nxAy_bM<|n## zZ>G1I0-5a!!z6^2c0%Y&iWFqVa6k5X*YQ@+Wz0AEoJKsb<$3(rX z{gf?fO#zEdE2r*h5&z{L@9~jW!#`rgcOQde(;|)j?K2KkuJ$my&wEv`n+GEJUahHi zqceWNkUyeX*ko8l;};~ttEao0V44u{(Vg5-f6ud)A~@rTQ0OVYErrN0HelZ` z;Qa~@`zd*EETLoob6q^ZpjOFvmK*~qos3e{OgQe^U<&?386m8mkPs}Va`@TIQ?b3d zZ`Rf>`_lqwcKs7sR#LHlTrplZR|qeZInLXa9Tg3)ci<1k{haJA3?UNG-5Pl1nbAXH z&Yo7pbuT7ddQ4O9i2?~T*^Im0n1CZ9DQ(n)h}ZqAqh$Q}^k7Q&ujMD}gI0CwpEq>s(Acjgvq z#3$2ufgzL&2};KQge4SL{w!eRD0{oGzA%1F6fFYirI-EB4tQ)r%iM%{HK*D)qVm3V4n~#N zr`wVxuuXHFyc`$u4A^hGqY^IknZ($Lx#a;RC#8mwRIQVvOA!ZSi6Wt@rYo`7fs!G{ zR)m3j0Y&;I7Hi0?@=a~>E1#M`?1kffx`l*^f`U+1%uT`XW}bIrhCyDQtura@iBHi4 zZpzz@VNF{!GdfIwAkDi_tLl{#XFd{WR5>foBk3OC#WyrdVDC}*1qF#CRZ5q_(%RH8CE#d5>>Yi8p__Eh$qHW5gjs6H!6qZ~4ii){OZ; zl{i#!!-P&03mOpGy}EMb`v~n$Fs#>w6-Po^S(S>k!?fe^xb!99G8GsaYgG1a1rrN! zHn+WW8cUpWE9*0$pQ?LDbPBoWAIk#xQMTD_VU(0+=+q{_VPfr-QF+K?0U&i zj#`uLTJq?T9b;o4s2Y*;@0U5mPbUchjO*F4(_bmnW-5!L-L*j%m9*78B@yTy;yMoEb zl4X_TbOG;*D4Pu8a~^il0nHrb@`-O5SV7|x*42I^b@rnFbQ<4ACRG*^qCWg{}ETYK5iT|hw zl8i=0k@cL7?MA_S@bmB^09`pGlHPRvt*wQC4TG%ufI(w0-F>f+Z7HWa-|-I2-7#Kv zV{}*6!rp35AO3zzLiuqu0E_(6tt2?*A!C^tqPgmSD|&`fGyO=s9o%)k!)!9Q1@z{1?5$BK768DERh zISF7oW)B)-A+HCGiTRk&8D!_k<_7&tz0q%VJ;yZ z;MF7y9|N7(RL$RE1zH-}|MkZwKwCjcu)YxqjpJoGYdC_~a&7cutBxINFUi_hW_9i+ z-5+t{_N|SNvg_lau8!_>3)QR45BvSomm#_J9@-_ftnJ0Im%ff)qGEl*4;Q~Mqw?BP zm*8IF9qQcHNv;_Jr?3~3F7tB@rFY$@$A@~p-__R>5acV=F5KxlyJ}qWKLyQ1`z|VK ze`Hu0wVo>ZUOOFbu4viE*wfvrA%C;FD_ZfHr8Zh~uynkwjD+Ko084#}y!LMV86&Th z>uipjZD4nuV@CKe$Bf{XP4ZCB7Id1wVdn0Ufqs72(8ZRu41UfErOJK;%l-R}kvJu@ zY*RQv$qiNGB#!eRgB$LWtL3@3%s(1_cGfiff@*&5@(tNsdDbn_Rq5lDpv}h$JHmdi z7RbKdwC`;-^}1m&zp9MVJzxG@i%DA1XxxL(aTdiXv{BNddqW{#^I?)-YJ7<6<>!m9 z2(~^TAQ>ZTNKv3h^g&BN$Zs94fkie$y|z*PmLj5y2M8@JHjw-;92LIZonlQX`<7Jn5{oKBzeKJ+kX7NICr? zvt(YVvK-p@lP`ymaDF6&EV(*&T0-#EuJ3rmaqjL}L*vcsHcsPLPJ3q0N9#k>;iwL0 z)F6Dz&>`kJ2yy$`U#hs_FLy*Rr-w;Rqt75nNODEQNr$T%8k0Lmu8_CclpuR24WDec z{6UDDgEK!_L4rywE+)PV!p*}ZaLHQ$+uy)&+f!pWfy1sGI~OrydF%iDNc872Utd2( z0M%cbTZi`nYD$R0?+5@bt%L1c5CM#41Xd`IkIOKC?t)WO5oppNHuN7GM|ViSrgltM}X zgFGEJH$5=*eY+;{>zUdS!Jtx>Ul8+~bsbhBOe`a6(vV&>>h&@YOd(YxWWInwHQoKq zfF8lu`IUKwsTv~T7C?U(oF=pSf<^(>&D#==SLHRvpGJ;^=}TC$ONT(41=;f=nL3)RfHL5>I6E_*bY^oPhJ1B@@k zE5>v-0kh;W#?V*XSrN+lMOpb8CU3Nfu;XFsqwZdkGK@BKr*u0kKCo%2s7`a^U|B{? zpa%OZDh|sKummom3A%mdBqX@aK&bL(Y-Hw79RS=5>x5P(U%y5qB%Ja^8PsxgS&2N` z?z6=Uw<-_=EE8jp_};!~K{4=f_K+Ob8XOfesq=tPd<<%AOzN>9>F_`(>yh9_w}`PY zLuVOz5hZ10^c!b15o$^pL@Lmk6+;~fx4A2ajlmoHL_46m2lB~c36~8XRwRUW7q3&q z?4He9z?ux}Lkuiz zds*(t(V1zE5E;$V#U&>3wdBG{GLq0bvl|uccFl1g%nX{07VpePN(D z>V(*k%|$1=j;n%pj4!`wEZV^~@ONCglr<$G)hJW7tTMUz{$_GEx24rwDYGP6SB}=~ zItUuIA0{%oC70UaRPJF}GGs*_hLn1N;OW5V`MECx>IN1HAhNt4(Goz}j9*}$!>!F* zUL2dyNwL6Vqs)+yIeJNs2yE-t!Fr>z@vqv~DbMd9r$1EN9Cqp8>a0EkvYyZ>aclV% z_JQsO9p!}VD`Oba8l|s&MmTac+ZCg#(4aE{i6c?mLPLW=q>t>d%h&+%`-JZ#P6aBB z!1hZ#oZS51o||*EF^I(pv$(H6#i#wjSKu#h`-BT7$yWoN>_x@v=S2eThkt>N^n*I^st1M-g9Rz7 z`>9!*#}q5l+U&n2EM|YQpK{a{oX;vz@Q9vTQCfM#7kM^jiipM>T6Y{L$#SBPW%#5n zV97!|v~*gnJDU)KL9DdzVteeQNg5xAwp3N$tHx@*3iugQ7yO-( zW0PIbNoPk?Qjq7K%h__u^3eS|Y!ZRCoX@H1$)mf)ir731$DTdwZ%BIv0BCGbe^4_# z;+)RsYH@0&qcl%gCn%hhg_+B2X%}rl!n>2A@j2IgU0pU*U8OMMOL76@(DZ5b2WU?Q zt4~1zOGu?$n*v23(sAj0IiIC=*tC6}_D_XsEPq>!N3ILK&zFIwns{!Zy33$AzPCa| z*{{jk$vuzxGQ_AQkhP@Ewm)QL`cJjL%XF=*snm-hiI9e%V9Lt-wApB!m`{5 zHW_(=W~%!qgKQ2(@sj3K+1g#yH=6nD^AHc;ZJygVl+ClzJ*|QU zxi8}V=CkrdVHHDD7=FA1Mi#0|0pPw1`URO^9Z?e}wTm!n*&(a+xW`^==I*h1lbWz!#)s+HVq2HPLy>RT*|yN?=2U&~D^AMk(*977UywDq zp7tOH4@NZP^6BI2&BfnzVJ*SSCWa9xdJF);)BOx`_UxZ%{vA;R+=U~0l$0f2aq!B(Z;0@x0iqs@19FshtjE!ZLAuu29zaPKR6X9)h0u%kBCS695xdRQD0J z%!bv$x#5ecyk2h9&9Qtm4X8Tf<9@-ppqhRFAu1J252Sc-a78T#&fS-S}zpdC4JSFfb zF-5xWinKQ*0GH@pJl7A^<@EB`-zjXu=(YE8Gkl!6rd-||>`4=0@YD;9yBPJAB$d9+ zf`@NtKRo%#`kbu!e|U(y)I)}yT1Ayq4fp6>+_dMpZ4+Ca=2~sK&DEP2_$2kawSUk| zs!cswSn3zuqmc)Z01SXOe!XeIL|Z*xtn){pIu2s+{aW~CLD9aK zp7u7cWVM>ollQz*O7z+0^)H9`DNc0@_LdZK486L@o;|jjPG1$Tpj#l-bldE%xV=bB6`(Dht%}y@X znhL^GeqtffX{IaQ%jVN!v$dUW{(knI-_jBn4{3y{ZvBTg2=-P%)lb$A8CPu3 z>cD#f-=r5UXHM^u%4ZeMtBv6^UmK&E$&IJ{J;dQ&k55uDAsza?&>4K;9`?l~(WiYc zs6xJ5Mqbb3rnvBxm#uC4q=$Od$Gv6K%w1PaN&|ohTHZ9Vh6V_|n>_R6pk!;7&PH`4 z5C}2YIz;@893?5xX`K#H{;081yAOCzP*YTJi);)_yyS4*KjazQj7>`_EGwrxZKw8g zXXR{J5_e>==4c?SyEb%dIYap{y;_PtT-_@+ z196_SsYH%*(!*KoMM=VxKQA|i7>v(V7EAaXhuRd^le0VK-cQEG1ir14OdBfi-}&H-_m|1cEt4-Fumz!8Qb26O)JafGGy?-^ z?BvUQ(VF8&)nbM-o>+nl>%45^zof{yx@D}03oEWgqo$%hdGVH_^^KkHVSB$bYME{I znJT$&j+zAlx~CPIbM3;IO9xt9_Gkg~35idL88slPxA~C(CY`K2>ZMYXM;5vDCd69JX&&pIWT&a+9}K^FeEt0+v$8ydj!$^+ z;t#yL+0|w^N|7TOTZt&K*u>(aDZnY!RZ0r(^ZuiKTwxVmT=b~VJ;e$^H8Po3LY_hy zhVxW&R>pdW*{GRu+?zLz#EoN#ySuZ?zU#NmKavV4}-_#8f9nQ&Q2wQ2TwVcYxJ zD}g$ZQ32gM*4;0$vn+^+#VgEAbQ5Ji>yh~8pIDBD^qM|xpgQC(?mx^(hLCP#4 zuG7W)xDr*LYD`eR0L};XN^WNr1mi#T@_ci>o zu6$ngbOkR23CcnlOfc%j7n*+HiG;BP#RL+mT8nKqx?R2g=-#mm0bnr@|GtAI9rFzT z8=@nUk{LRMjdeeCMuxZUCo^U5TZ|%Glz)1$^=w2qysl+AruB=wlL1vA5sSppJT_S0 zy))F5l5J2hnwqJq;$xmX6U94nFkNr-3ztg9QqTv>q!`Plm^>|yO@|S2R!Gsi&ck=| zWLp78hgDedpe5JGQ#u(5NF(mf`OnXcD&=QPO?NYax?-iy z96N1fqEP4jA7XLEO7OOP9Xm;O*ze2FLSexdZdv^psm#|k3KymV)ECj7iMwQ)=r+;vzji6={< zMw#hD@?RB`M0-VJ!W|bIWVVqqEWg@=)5Q3-u;DEdwp(sF)#+2NyfXp}*+1`7M4F|& z+()l5SJ!iCF#B|MUjH+Ospa#@^cM59X05c*`|pO#{NpGmLinu)y$?hrx+9ez=sZ<| z@cCe^=IN~#sn=4{Fer!(DHN)dZ+cH9ru@jgbonLC0(pTcq=(6d7ZUHZzZ?Is)wW2C zELZwNVneQ+t!0CY^OY66!J4oCc7K)!fDy|MZu|HOyxIQ!ijh}a4V#KT+akPknTbV6 zoclq^_|vD&-z1X8Z_j^O zW{Q@^PbUdyT^SLeXwE0bv0i<1I4@b>nx43Fkbfb-zLBzNF@LYs=6Gqr#Z7dWMf0h0 zQ~yu{9iWUXxKJHh>3sMsq>Eu;R^hwp&xi!a=?a^(-;$o6EH}P2oE#84^-1jcJY5nK zm>=bVQvU9`ETElR5`D;h4_neghEdhEw`-Twif_R4yXk8pl|B7-F?OZ-lts0a8^ta+ zk~rT%zG3c#hVq6voIvGQU%th@;Iap_=r}zwHVW{mk3zapauw}vq-&q=9Qq%!dOEg8ucojOw^LW$&bKeYX|I;jawKl; zYKr+LXp#Q!GKx;T(w5$A#V$7c5%>=D+=x|&&NU_*htM4UcuBwe zxgXY~qjg^}vAeDB`eZ(8Y6&1M-e7t&L#8rp(w$gJu$qzAFK1%p{$MCT{FAUt&uSMg zNseDW@=tGCTaK-vEUvzOw|tS2_tY_ayjcScj~koKA1QG z#sRaUAV*Cs_k=f=6E5`gn44?d24DSEX!GMHD;=j;^om;y42m6`7V<-?_BkA@qG0Hi zCL!qI3x|G0ww7o|0cU0+wx?>u*wYcbb+&1Y3bh~nWRgxzJ;f55w;rlzNH;21Pr##9 zzc%bOJMl#;XZ;44ki?FUsgJK;SNE~Yvy>%`v3+=L$|$t&dp_7${*1o&NWcW82WZBI{;Aps;>^}8gm%+{w@{l|6r)KxDcAG^#} zKIolfUq{%MFDuwr(2{8ibXrG7NH)IwET7+WYUld&9d@xnnC@9H#YCO{HE^O(y@qsr0ZS0YP7J;(47hCv4mG!sy7r&W?TKNN}Y4UbL zQ~92M|MgYxlv$&JRgiqtTm_n@f7Yt!<-ZH&o}nRdBpHlg6Xi-RwCE4-)np0tWljqR z#2Y)dMN^^)yIv|QuO5eB=<_nH#aP*-M7(7x8rEs#S#NXH^+u6%D3Ev(;JK`_JGwBN z(8svIF(35-M&98RM1$9lyqd2F!o7@WFHx|3Z>4x$#w zOx}_UNOQ(TT`y=@MwDxE?%Oi?Y(xu|^t`PUC*U(Jy!Y7Es1WEvXf=2A`#_T|!xn1jPx=(L>?Y`$bH^jnRowyAg%k}>3y?U#8?dH53scv*;}}}i20>f#H9V@ zFYa%j(NyXW#Az9PpevUj6Xd{3@Fo~L41x2ER<_)5OhX!;Ti+vTyJfEC*!0P}nz@bR zGqKTy3qb-)CY=AJA!ca)Ks$bIJY<{RE=iDx-$rM7QAa?al=%9d?XF2@ z-fZ?1M1MhI;yAGwlChPKw%e>Xc13ORK~uBNK*8o*mGW!NSl1%_9kS8^>86GZ!{Pi z!v6Z$o7e4lt2gdhQx+hXwp?3Igt)4_N$m))doRm)VO5S>G!0Z3Z`Vjc2ixKa7mY|^$n4`+vMVTedQrMA7H5dMxuL@ z{Q9hfrFR3#Y`kyQEK*Gre7O8=qO88MQRFguaevwWq(@u05brrV(2?AOse=Y^!&T&i z+uIG0q@iRC!Fp7I$~^?VDkU!R!?F`nPDS!m&)Hb^kB4RGt3D3oLnPxB>UYlsXMOnI zL@U>)y^?DCFx5}R8C0=;=r$6<^Qqolq|@TqtHco2)1{uA43Q74ivq8LU;+U22hV^e z`%8Vh;2jPH-UytNcFwHUPk|NfGBRoghP5gxEp&p_c*itN!8Z=s z!jnwI%?Xr;>#32lU3(k}=ol(2Go=d>q48J`CPxe!C!KZ<5*5>XhV0KK#YyqbLv7{M zxD=&b7%D^cBFk7_JS;`+A)Exl%p)nKWszyuPBv_{O)JqtauSh-o#;o6{4z20!ceV2 zgs$KFo;LR%rjaz*U0=#Sb-&ZJOEJCa&_vCcmd;b#Hh#@1Di2Lr=?Tk*G9>ot({o?(INx`=F(Oq0Z z!#^lsn~3M5Y*1^@rYfyOF0LMygRXERgCg5=xyewT2Qpk}$%NM&038Kz2^aLYFdySz z!^=r}zynjn|7=t02%^pt;)Ov6IppQlEVJ~`9Zb-}<*;A2qs9wiwmrG^30$1I<^9;< zY`O2F$YQG2_kkz%O1bDpsUfM)ol>lK#?l|C`1(#5sl2BR>1O`kok}xgvgBEMpJzL1 zfffYM*GfLDtpapV=`Z|wOzpo`dX|D1%`h>poE31$b9$aRxlD;*f3ALG-K?eP)1d8E zT9LYZF(qW&{1XN!nW2tmFiCmYvzS2DS5yL49-vq6t!Y)uJP+LMDRR9w$F^eEMz&v$ z!20tf>n`l6%G8|f4mp{yX*!QTIc3(lE*6}D+Sgf)%VZg?lg5STqMHzKfap{+J9$-T2DqRhdKhLhHt1$_yW?k;6|2yMx1kW^?Xu(n7u={aIJsg z%x~e!Z{akn&r|yDM`uh=HW;L%){d*4oUKS)B1^)Po5V>@Jp6BWn=Wb`0RV|33j`tS z!J;0jtzzQf67wGC1WEO%$VM7O)vZ4hK%jxV{W}H54^VsCD(L%im?y>T1t~GBPZF8f z?&gz2j^&8x_f<`X1p{-iyvokDzGhZ@`)(h?6ZUbTTb?D|`PGc;ea|2BwK}byw?e^7 zB)|uaC2~Nh-Ha+w8{KEAkj-_?K)+Yww|C&s{VJ)Rb?)%GQUyOu*3GoWV`=E*y4*z( zr(V(jm1peTdTY_l+NI+~s$JJ!O!c78_5cLIGpSU0E#1_SR1?yN73$fTW4$JsAU_~Z zMc%PU-F~>I+9ZKL!2Z5w*RW=XX_L_J-<^qho*B93+yHX6# za+bz32AsM$Etx56cok{(H_q=5E&x>|mZYK##b$0eB|NEC0e4!P?i-k7v2i7$fk?>pa=+>V2Sb++h{X1n( zyk&Y)RM>ZXuw#muvjUJS7l}3=a5`#d3^NFpxB+J4@Wd7i@x8(xHcHN#HSi>LKRfGK zn5ORZ@7ipmIG67A__>o6k?$&&vbDXZdUhlI@&s;1IHl_^F zlxh*$V`uHg9Qir;+`{M7Du)>X?0zHoB;Ol={Qd`f8kiT+ro%at@-CE*GbK|buBxEArTJEW^ouh2N?7@?U(_0gO z*B{EwardJ~k!3Njn~81E`4f5MBN80!A98Iyz+5o(Jd`(Ys&c0bwjPHOnic4UX~w{$ z4qWQx=F^@`7lvBg+Vd^|b>fiUDRY)Lmc^PE-gCvCEoRPVK3bJev=&0e2mSb(BvaL-?Q+%i zu+u{YpE&j3Y*^=i>E67nt)~Of3l;2nrl>LJ{fSgDkM4W&i|;%ZxS$STYljyS7OWg&Ru_@OyyvqrX2;Wb5Bo1 z|D&mFHaUO+_=@M!;ef@6^oX2rb;TZ$w1RS*7=}orDs)KMLXq=)Y_y8irw5o^M(aXu z=S!#ZXMM^PN7;QtDt``X9?r=3IWLfq{v``u0{|Q%#~ubyY(WI#1@grV?yYHgw=w!j zd0$pH($Mp<%-4xOv7L-^bfQ}A5Vc&U$bI{?bsXkByJbNYv~*C-TY0m-+0aV+5AM(d zT>}RI0DOfY`v4Vi4AVeH`ZnHT20-_Ddw0r6%nhWs7t!~%v5MlEv(Urnd5Q9b;C$p7 zD>-b!LNrtN9{4DVi(BeEIldz|f91g>{l_gdKr8!5B;vGE?w6n;-@0v7q>8pjV_8j0n5pd4xp z7MV$la({@&rPL<}pz?!d<9#~rAr9TMy|yQfs+y5wChnVWn}pNH%Y|D-xlLB;sEF8% z1er4%W1rp#`%z~S2ff3_jhsSp{9EP@03ZzihcFUwefdI<&GCUB`Os2Q<$8kY<_wR1 zeaEMG#f}!g8pD~uQTbS@x#X?aiww(uoSfZ@GO}YlC>-e3{=!_pPO3au5&?iNE%^!H zHZZ^h@@+6M;H$RN^DK(^Jo<$V58!Am^{D;*AQ&N%h?QC10Tpjm@``>44JKl9CDP_r z|L9~O%B`Dh8{d1FO5(G5#as-_y zNmt$60-vmPgvBkCCX(dxGZgTg(P9_=5SBw(zS#O=u3b!?nIky{<4I6=BTw-CzeqQ! zwK=~+MsOeA0AYQ41SCn?u15xa#K$Jw{UxsGRLo^)loy6I4DW7D*9uG)-sIoJ0WaMt2TC z=LM-NSz^?nK~qlUMfGD!wCmIO3=E=;tL<$Yv=G~21#8s(xCe|Bi->_)Zmjs#1LeG? zd0~PGEMy{8K7BN>8OJ09=c3j#sy~ma$7gk2aufQeJ$TV#pY>+O7XTdVn>rv$V3~#5 zND>V?cFA|c=@$G5t?fBBax!=b!7A?$eE}$IT2PwL#EE zz99RF%#yiVQvwXj-M|un`CmeEb5*jEX7?f@LhZ-0TO>Dk&VN1kf8Sg8gW1r;X3%JV zZe(|^n)O@EVdY

(}*FOdVYF@Tss501#x8H1iU!Iwh8{@XlCUTjJYPk9VGHrW?P= z#EbsCIt~JZ>Y4I;H;eprGk;s7vaLtE;ua}@UZO+?;I>}|&N*o6mryb7vGQH@CEfZP zZdjl&Q?G{XD>|9HN{(8KuW4dl2g!D_x^@Sk_j3mTjKF}?TH=!i_;} z-go&TSyCRh&j579NFBiSALX=BFs3Gs{uMsPcU)4vvsc`(&!?-Sfo6 zh-3o1vW8KF$M)0oj!7ERiROM8U>oef=!w0T8#dZ86~|Zyr=zp7QEauALjpaUVE}sj zHffx8Z3x=aof=O2O(kNl!7>jZI9x^baGLJ*S|05`wZIo@483q46M4ux`&VQeNdw@@ zr@B%^XKi+K%A;2UysC?vZF}hBW_%C1o0l>ri0*K=|7&=-@LYjjnWQy>FVfw~xKn@M z#oS`1aYD=gP|q^^`k3sO+I?r*>P1BQ(#(g~17iOg-Lw~yaOLMuM`Du#*wIFC0Ls_O z%Q1pS_WQJ6V$_^lPoc1-By3gLJg4hcUpRJkAyw}vojQUa&3+fcp^5%1_MQwxJ*%IH z(L9R>j$3=j{~vIcEs!d!jiLB*y^2(N$e;N0;^ zbQkPNa3~m6Q?}AE(KP$V?EbOq{-mX0ZO$G2bI{BX)Bj)H?SAI2+*EGdP?;y+1CbE` zexMN@0@r_)!j9vBjA-}zD$MfHyX*APTo5e&mx2$$D`^-BcC0N^pZW?HoWCb* z0EUT$w(r82i&W3@jm{H74_DusjP)o3$S^sj0XovU(k3=JurWXLMQW%HxrgO7xWjgv zs8Hp)q&|To8!@5GFM0p1WWzR^qW_F`y%cy55cb&2}ObActfhYr?E9(3n5{nN-b+5D&ykdf3V8=vLDcU2r*x+am zCRos5=pS}^1R$NIfzDI}U?to)1G{PE0bn1{KmY`wi7EC+@P-dT6z~Y^>6Jg>zi|tq zigLY#q;|)Bsh9BOvm3_SZ~m1E0INe105Ff9_|ILY{QC|i7aKcf7Ds**LKH^P?IS@A z4Tf;BvuD8^&6$IlJ%DKC+lsR)_LZnPz`YJUAqWIKTK~$Z~vwz}15Vfg*=pYBLNMHmwS$#N4_5dLp zZU==6>PQ$A4<#3n%n}N=@c^)dPzP~#4?ul5&M09!s`Ugz=3?7C=QcDz9eSIdcFg#` zp6CEbCKUW_x%5Zf$CjQf<4Q0m$=~ARhQ&1C$Q1!_YnVB<4gh5i+~8zHqVQ<|W_th& z1_fwOAOIRRRwj6xrWW{fzWswTb9@89XixmXeAF!r!1Q>d9rZK#p&C5jdVG6zoltl? z-tmyYFrXk0A@(LPr%(nMAlRSY+{=RqK_0xd7J{WPq4GQo0I(iUAKo?s_kb+JIP5ws z!hF{Q5cMZNUSDX{KGmCNuC$SD2S>qv>EE}aDTREq0drkW)~B6N7}nMi0*;pe!}mXE z1pnkdMhX5X+^%dI=iN@n}f6dc$N>z zSa9W3a|D9#0?F5feAD!3k@Mw}G=4smz}Cz%A4fV69mQ&LX)drRya)@H7Ozq#jeH9= zD^5R=k7Yn)vu#q#!=Q|UpwDnb(ckz+u(r-3Z!fEGVLPlpPr=ZI+63UbJ&w(dWJdjY z5ktMNEF6bgUz>~+CswmZDqFpnq}*CQR+y)RL_SuY0$t(8lY{vVG4%q^W+8G^pAseg zd`2$Ww#+#9Nfz$omRcA1j39U_7%d%6!~_9idzs{8*)u_()SuE3qS8`v#?oZ400!G6 zQk-C^JR>*#-rverREZ7SA)KVXj3ggLqow(yzFR*rxk7D9R!5y`Cc6Ji{W(u_r{blP ziR;EpQ6g`pI@wh(CEl(j{QY>@Qe2JdDy0A4Pc62EIU2aP{)7Ma$O%v)2jEyFS=d@A z|Aa`RaiH|&0|4d@l>b=E%l7_f6kRV$)RzGK1b-1Gz|xk#k?oZJ@fs3-=XQF}lSk!e7w`22l5UcmxOvJ`{d{ID`cOAmC#E_+xeaYi`x^ z=wx?l7l2Uy6LfCkD@M}0lm(DhJ-)4Rja{p&F**0@>7LF%YhEAk+~SkHT?qmdZ~K>+ z4*LlTA1wOVS{1lK3r zq>|I#Hos~I4>wQ>S^ZOJ?IwI1xSChHUDQOWQ&Htuaf^>nu=4hw{Q&^`);kQ-2#@mi&GD&&%)ic18ocb<{v+d**-p-AyHUc-d`+x=Q~6h2@NZ9};;-y=YO2nYl8p-3n#s%k_d>IFQF(E0Bli+Ke8uLn?X@k!qu i0e}O53XuSChYsbOs7D^^BkEEJi5igqSCIdQ3jYV%PqqgD literal 0 HcmV?d00001 diff --git a/Telegram/SourceFiles/calls/calls_group_call.cpp b/Telegram/SourceFiles/calls/calls_group_call.cpp index af42fbc5b..0e94602f0 100644 --- a/Telegram/SourceFiles/calls/calls_group_call.cpp +++ b/Telegram/SourceFiles/calls/calls_group_call.cpp @@ -201,6 +201,17 @@ GroupCall::GroupCall( } }, _lifetime); + _instanceState.value( + ) | rpl::filter([=] { + return _hadJoinedState; + }) | rpl::start_with_next([=](InstanceState state) { + if (state == InstanceState::Disconnected) { + playConnectingSound(); + } else { + stopConnectingSound(); + } + }, _lifetime); + checkGlobalShortcutAvailability(); const auto id = inputCall.c_inputGroupCall().vid().v; @@ -269,12 +280,6 @@ void GroupCall::setState(State state) { if (const auto call = _peer->groupCall(); call && call->id() == _id) { call->setInCall(); } - } else if (state == State::Connecting || state == State::Joining) { - if (_hadJoinedState) { - playConnectingSound(); - } - } else { - stopConnectingSound(); } if (false @@ -462,9 +467,10 @@ void GroupCall::rejoin(not_null as) { MTP_dataJSON(MTP_bytes(json)) )).done([=](const MTPUpdates &updates) { _mySsrc = ssrc; - setState(_instanceConnected - ? State::Joined - : State::Connecting); + setState((_instanceState.current() + == InstanceState::Disconnected) + ? State::Connecting + : State::Joined); applyMeInCallLocally(); maybeSendMutedUpdate(wasMuteState); _peer->session().api().applyUpdates(updates); @@ -903,6 +909,9 @@ void GroupCall::handleUpdate(const MTPDupdateGroupCallParticipants &data) { } else if (muted() == MuteState::ForceMuted || muted() == MuteState::RaisedHand) { setMuted(MuteState::Muted); + if (!_instanceTransitioning) { + notifyAboutAllowedToSpeak(); + } } else if (data.is_muted() && muted() != MuteState::Muted) { setMuted(MuteState::Muted); } @@ -1269,19 +1278,37 @@ void GroupCall::checkJoined() { void GroupCall::setInstanceConnected( tgcalls::GroupNetworkState networkState) { - const auto connected = networkState.isConnected; - if (_instanceConnected == connected) { + const auto inTransit = networkState.isTransitioningFromBroadcastToRtc; + const auto instanceState = !networkState.isConnected + ? InstanceState::Disconnected + : inTransit + ? InstanceState::TransitionToRtc + : InstanceState::Connected; + const auto connected = (instanceState != InstanceState::Disconnected); + if (_instanceState.current() == instanceState + && _instanceTransitioning == inTransit) { return; } - _instanceConnected = connected; + const auto nowCanSpeak = connected + && _instanceTransitioning + && !inTransit + && (muted() == MuteState::Muted); + _instanceTransitioning = inTransit; + _instanceState = instanceState; if (state() == State::Connecting && connected) { setState(State::Joined); - if (networkState.isTransitioningFromBroadcastToRtc) { - // #TODO calls play sound?.. - } } else if (state() == State::Joined && !connected) { setState(State::Connecting); } + if (nowCanSpeak) { + notifyAboutAllowedToSpeak(); + } +} + +void GroupCall::notifyAboutAllowedToSpeak() { + _delegate->groupCallPlaySound( + Delegate::GroupCallSound::AllowedToSpeak); + _allowedToSpeakNotifications.fire({}); } void GroupCall::setInstanceMode(InstanceMode mode) { @@ -1342,13 +1369,9 @@ void GroupCall::sendSelfUpdate(SendUpdateType type) { }).send(); } -rpl::producer GroupCall::connectingValue() const { +auto GroupCall::instanceStateValue() const -> rpl::producer { using namespace rpl::mappers; - return _state.value() | rpl::map( - _1 == State::Creating - || _1 == State::Joining - || _1 == State::Connecting - ) | rpl::distinct_until_changed(); + return _instanceState.value(); } void GroupCall::setCurrentAudioDevice(bool input, const QString &deviceId) { diff --git a/Telegram/SourceFiles/calls/calls_group_call.h b/Telegram/SourceFiles/calls/calls_group_call.h index ce314216b..fe54a15a9 100644 --- a/Telegram/SourceFiles/calls/calls_group_call.h +++ b/Telegram/SourceFiles/calls/calls_group_call.h @@ -85,6 +85,7 @@ public: enum class GroupCallSound { Started, Connecting, + AllowedToSpeak, Ended, }; virtual void groupCallPlaySound(GroupCallSound sound) = 0; @@ -151,7 +152,13 @@ public: [[nodiscard]] rpl::producer stateValue() const { return _state.value(); } - [[nodiscard]] rpl::producer connectingValue() const; + + enum class InstanceState { + Disconnected, + TransitionToRtc, + Connected, + }; + [[nodiscard]] rpl::producer instanceStateValue() const; [[nodiscard]] rpl::producer levelUpdates() const { return _levelUpdates.events(); @@ -159,6 +166,9 @@ public: [[nodiscard]] rpl::producer rejoinEvents() const { return _rejoinEvents.events(); } + [[nodiscard]] rpl::producer<> allowedToSpeakNotifications() const { + return _allowedToSpeakNotifications.events(); + } static constexpr auto kSpeakLevelThreshold = 0.2; void setCurrentAudioDevice(bool input, const QString &deviceId); @@ -232,6 +242,7 @@ private: void checkGlobalShortcutAvailability(); void checkJoined(); + void notifyAboutAllowedToSpeak(); void playConnectingSound(); void stopConnectingSound(); @@ -260,7 +271,9 @@ private: not_null _history; // Can change in legacy group migration. MTP::Sender _api; rpl::variable _state = State::Creating; - bool _instanceConnected = false; + rpl::variable _instanceState + = InstanceState::Disconnected; + bool _instanceTransitioning = false; InstanceMode _instanceMode = InstanceMode::None; base::flat_set _unresolvedSsrcs; std::vector _preparedParticipants; @@ -290,6 +303,7 @@ private: rpl::event_stream _levelUpdates; base::flat_map _lastSpoke; rpl::event_stream _rejoinEvents; + rpl::event_stream<> _allowedToSpeakNotifications; base::Timer _lastSpokeCheckTimer; base::Timer _checkJoinedTimer; diff --git a/Telegram/SourceFiles/calls/calls_group_panel.cpp b/Telegram/SourceFiles/calls/calls_group_panel.cpp index 68eaf2f27..01fe119ad 100644 --- a/Telegram/SourceFiles/calls/calls_group_panel.cpp +++ b/Telegram/SourceFiles/calls/calls_group_panel.cpp @@ -281,6 +281,30 @@ GroupPanel::GroupPanel(not_null call) initControls(); initLayout(); showAndActivate(); + + call->allowedToSpeakNotifications( + ) | rpl::start_with_next([=] { + if (isActive()) { + Ui::Toast::Show( + widget(), + tr::lng_group_call_can_speak_here(tr::now)); + } else { + const auto real = _peer->groupCall(); + const auto name = (real + && (real->id() == call->id()) + && !real->title().isEmpty()) + ? real->title() + : _peer->name; + Ui::Toast::Show(Ui::Toast::Config{ + .text = tr::lng_group_call_can_speak( + tr::now, + lt_chat, + Ui::Text::WithEntities(name), + Ui::Text::RichLangValue), + .st = &st::defaultToast, + }); + } + }, widget()->lifetime()); } GroupPanel::~GroupPanel() { @@ -507,13 +531,18 @@ void GroupPanel::initWithCall(GroupCall *call) { } }, _callLifetime); + using namespace rpl::mappers; rpl::combine( _call->mutedValue() | MapPushToTalkToActive(), - _call->connectingValue() + _call->instanceStateValue() ) | rpl::distinct_until_changed( - ) | rpl::start_with_next([=](MuteState mute, bool connecting) { + ) | rpl::filter( + _2 != GroupCall::InstanceState::TransitionToRtc + ) | rpl::start_with_next([=]( + MuteState mute, + GroupCall::InstanceState state) { _mute->setState(Ui::CallMuteButtonState{ - .text = (connecting + .text = (state == GroupCall::InstanceState::Disconnected ? tr::lng_group_call_connecting(tr::now) : mute == MuteState::ForceMuted ? tr::lng_group_call_force_muted(tr::now) @@ -522,7 +551,7 @@ void GroupPanel::initWithCall(GroupCall *call) { : mute == MuteState::Muted ? tr::lng_group_call_unmute(tr::now) : tr::lng_group_call_you_are_live(tr::now)), - .subtext = (connecting + .subtext = (state == GroupCall::InstanceState::Disconnected ? QString() : mute == MuteState::ForceMuted ? tr::lng_group_call_raise_hand_tip(tr::now) @@ -531,7 +560,7 @@ void GroupPanel::initWithCall(GroupCall *call) { : mute == MuteState::Muted ? tr::lng_group_call_unmute_sub(tr::now) : QString()), - .type = (connecting + .type = (state == GroupCall::InstanceState::Disconnected ? Ui::CallMuteButtonType::Connecting : mute == MuteState::ForceMuted ? Ui::CallMuteButtonType::ForceMuted diff --git a/Telegram/SourceFiles/calls/calls_instance.cpp b/Telegram/SourceFiles/calls/calls_instance.cpp index 2be9e59c4..1ab8a8c1a 100644 --- a/Telegram/SourceFiles/calls/calls_instance.cpp +++ b/Telegram/SourceFiles/calls/calls_instance.cpp @@ -146,6 +146,7 @@ void Instance::groupCallPlaySound(GroupCallSound sound) { switch (sound) { case GroupCallSound::Started: return "group_call_start"; case GroupCallSound::Ended: return "group_call_end"; + case GroupCallSound::AllowedToSpeak: return "group_call_allowed"; case GroupCallSound::Connecting: return "group_call_connect"; } Unexpected("GroupCallSound in Instance::groupCallPlaySound."); diff --git a/Telegram/SourceFiles/calls/calls_top_bar.cpp b/Telegram/SourceFiles/calls/calls_top_bar.cpp index 3e8467e94..1aa9cbfcc 100644 --- a/Telegram/SourceFiles/calls/calls_top_bar.cpp +++ b/Telegram/SourceFiles/calls/calls_top_bar.cpp @@ -57,14 +57,14 @@ constexpr auto kHideBlobsDuration = crl::time(500); constexpr auto kBlobLevelDuration = crl::time(250); constexpr auto kBlobUpdateInterval = crl::time(100); -auto BarStateFromMuteState(MuteState state, bool connecting) { - return (connecting +auto BarStateFromMuteState(MuteState state, GroupCall::InstanceState instanceState) { + return (instanceState == GroupCall::InstanceState::Disconnected) ? BarState::Connecting : (state == MuteState::ForceMuted || state == MuteState::RaisedHand) ? BarState::ForceMuted - : state == MuteState::Muted + : (state == MuteState::Muted) ? BarState::Muted - : BarState::Active); + : BarState::Active; }; auto LinearBlobs() { @@ -293,17 +293,20 @@ void TopBar::initControls() { _call ? mapToState(_call->muted()) : _groupCall->muted(), - false)); + GroupCall::InstanceState::Connected)); + using namespace rpl::mappers; auto muted = _call ? rpl::combine( _call->mutedValue() | rpl::map(mapToState), - rpl::single(false)) | rpl::type_erased() + rpl::single(GroupCall::InstanceState::Connected) + ) | rpl::type_erased() : rpl::combine( (_groupCall->mutedValue() | MapPushToTalkToActive() | rpl::distinct_until_changed() | rpl::type_erased()), - _groupCall->connectingValue()); + _groupCall->instanceStateValue() + ) | rpl::filter(_2 != GroupCall::InstanceState::TransitionToRtc); std::move( muted ) | rpl::map( @@ -465,9 +468,14 @@ void TopBar::initBlobsUnder( auto hideBlobs = rpl::combine( rpl::single(anim::Disabled()) | rpl::then(anim::Disables()), Core::App().appDeactivatedValue(), - group->connectingValue() - ) | rpl::map([](bool animDisabled, bool hide, bool connecting) { - return connecting || animDisabled || hide; + group->instanceStateValue() + ) | rpl::map([]( + bool animDisabled, + bool hide, + GroupCall::InstanceState instanceState) { + return (instanceState == GroupCall::InstanceState::Disconnected) + || animDisabled + || hide; }); std::move( @@ -557,7 +565,12 @@ void TopBar::subscribeToMembersChanges(not_null call) { return call && real && (real->id() == call->id()); }) | rpl::take( 1 - ) | rpl::map([=](not_null real) { + ) | rpl::before_next([=](not_null real) { + real->titleValue() | rpl::start_with_next([=] { + updateInfoLabels(); + }, lifetime()); + }) | rpl::map([=](not_null real) { + return HistoryView::GroupCallTracker::ContentByCall( real, st::groupCallTopBarUserpics.size); @@ -616,9 +629,12 @@ void TopBar::setInfoLabels() { _shortInfoLabel->setText(shortName.toUpper()); } else if (const auto group = _groupCall.get()) { const auto peer = group->peer(); + const auto real = peer->groupCall(); const auto name = peer->name; const auto text = _isGroupConnecting.current() ? tr::lng_group_call_connecting(tr::now) + : (real && real->id() == group->id() && !real->title().isEmpty()) + ? real->title().toUpper() : name.toUpper(); _fullInfoLabel->setText(text); _shortInfoLabel->setText(text);