From 1409d38ac3df589f9d0ec55541f5e70525ce9cb3 Mon Sep 17 00:00:00 2001 From: John Preston Date: Wed, 25 Oct 2023 11:00:22 +0400 Subject: [PATCH] Improve reply options edit design. --- Telegram/Resources/icons/menu/link_above.png | Bin 0 -> 450 bytes .../Resources/icons/menu/link_above@2x.png | Bin 0 -> 725 bytes .../Resources/icons/menu/link_above@3x.png | Bin 0 -> 1029 bytes Telegram/Resources/icons/menu/link_below.png | Bin 0 -> 454 bytes .../Resources/icons/menu/link_below@2x.png | Bin 0 -> 761 bytes .../Resources/icons/menu/link_below@3x.png | Bin 0 -> 1017 bytes .../Resources/icons/menu/link_enlarge.png | Bin 0 -> 582 bytes .../Resources/icons/menu/link_enlarge@2x.png | Bin 0 -> 965 bytes .../Resources/icons/menu/link_enlarge@3x.png | Bin 0 -> 1378 bytes Telegram/Resources/icons/menu/link_shrink.png | Bin 0 -> 542 bytes .../Resources/icons/menu/link_shrink@2x.png | Bin 0 -> 991 bytes .../Resources/icons/menu/link_shrink@3x.png | Bin 0 -> 1324 bytes Telegram/Resources/langs/lang.strings | 19 +++++ .../SourceFiles/data/data_chat_filters.cpp | 18 +---- Telegram/SourceFiles/data/data_drafts.cpp | 19 ++--- Telegram/SourceFiles/data/data_peer.cpp | 34 ++++++++ Telegram/SourceFiles/data/data_peer.h | 6 ++ .../history/history_inner_widget.cpp | 72 ++++++++++------- .../history/history_item_components.cpp | 36 +++++++++ .../history/history_item_components.h | 4 + .../SourceFiles/history/history_widget.cpp | 6 +- .../history_view_compose_controls.cpp | 6 +- .../controls/history_view_reply_options.cpp | 76 ++++++++++++------ Telegram/SourceFiles/mtproto/scheme/api.tl | 2 +- Telegram/SourceFiles/ui/menu_icons.style | 5 ++ Telegram/lib_ui | 2 +- 26 files changed, 219 insertions(+), 86 deletions(-) create mode 100644 Telegram/Resources/icons/menu/link_above.png create mode 100644 Telegram/Resources/icons/menu/link_above@2x.png create mode 100644 Telegram/Resources/icons/menu/link_above@3x.png create mode 100644 Telegram/Resources/icons/menu/link_below.png create mode 100644 Telegram/Resources/icons/menu/link_below@2x.png create mode 100644 Telegram/Resources/icons/menu/link_below@3x.png create mode 100644 Telegram/Resources/icons/menu/link_enlarge.png create mode 100644 Telegram/Resources/icons/menu/link_enlarge@2x.png create mode 100644 Telegram/Resources/icons/menu/link_enlarge@3x.png create mode 100644 Telegram/Resources/icons/menu/link_shrink.png create mode 100644 Telegram/Resources/icons/menu/link_shrink@2x.png create mode 100644 Telegram/Resources/icons/menu/link_shrink@3x.png diff --git a/Telegram/Resources/icons/menu/link_above.png b/Telegram/Resources/icons/menu/link_above.png new file mode 100644 index 0000000000000000000000000000000000000000..1f8881dfebec24aa4af0e2cba3b37ac59fd5a39a GIT binary patch literal 450 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1SIoCSFHz9jKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uv49!D1}S`GTDlgfOvls3F~mYJ zIYEN;fj~lXa`d*Gn}2_Q|N8aoNq(UPnzPOG|FN^>-`itoV4!eZr>yMT+UV`~_SNoQ zy7cLpnZ}dV{p)^zTRU;0;K?*b-<_qer)}9%QdRZq<>lp#ztsKa{CIcQT31)MBU0yx z#K|K^Ncl`;4EIb=lNv1UQoOri!%a$oq zr@D$AJPK6({oC8y^?!aahBpYgrKYAdhGr>mdKI;Vst08Qqwo&W#< literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/menu/link_above@2x.png b/Telegram/Resources/icons/menu/link_above@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..61c53d18e377cbabd4911b2117693cf80b01edba GIT binary patch literal 725 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1SD@HZMn+SQniz z&Dnl?`e{|QKDWgJVw|a)BbNq6t_&$yaW}7?UA_JA#;COhsTMNFJU6v0;QYNmMo)Rc z?YFN=tai5S5M-b9P-|b@`h@`U1IJ!}?dq|e>9enS!u|K+iv`}S@ljKrv`e99 z#fAR+t{39V4xHA_^742gyMK<;5m#RGrMKUTZ9ZL5ye~$tfW_hLxBTtV8#bm{%bR6w zm5Mtd^vZAf;j`?*-b;hhHqX56xv7&&mXCc>e}esaah7JK7p)E7tu2;c)_gnlY?|?f zuYM_3E}}o?izvJ^`e7)-!>0OX)9+WgX0ua_IOltPPc(OXSnY6VqQ)`RxqkOg94`^% zKjxw&*y%EFp}-&g!zs)Cfsxyw6gA`6MbbAj}p6}`67?Q#I zHuAi;R-nkc&YMmz+Go8zwP5X*2@^B~J2QmWF1q00B%qjaS&8F6m*JtgJHnNw^4xM0 z5KLlm4Cr=P;Tk#ZmVWj71AFwGC-0qHyjytB<73w8=Pd94+_$s*-OQQO#C}a=TEd{| zz%>C#)w4!LNB>m6YPR@p-u>IRt7~g*EiEPG<*#p($a~@J?7TGS<@ej~fBvkjs+tvD zwpPe;?z!2sXPXDr|8Kl~=1fnRYT*G{Ik|m%_tqZwvZ|@9{8+VD#^A_u2}w!K>8Is4 zCEa=U?Aa0VWn34Z7Tvvj*D&mpsha%t*QNXKujlei*>L;qzWw{t*Yx%EEnBwi#=}F0 z4qdw@X3diK`SWL`)7e6&AAbzd5)J$Q@L^(kx%nNZ8L9#tTefb^&C4_5E?`ccT# z*s)_z)^N2p9Zh0bsn=t#~4V61V5P`nDBgU*y=UcYV7jOW-rz8N=h)7 z;E|S=J|n-Q)oG#r;=1w!M~=9x4NDG{laZO>qsI12(a?h1_u8*tR^3c_8<--ed}}^; z&hKa4*8ThMU%jfTzgp0+Gg@nE(w&68ynKA8l5a*FcRR!uwtDN{y|GQqVFv0C=k>X? z>!p;Hna%X^`e!wF-TwXZlG=xKg*p!~olY^5m6i3{=FKZBFPCmD-f;SUwdq|JbFMja=7dbUar-uR z{(=Y2Ge3!3YTA{=&(D9N#CM0Sot@U=bLY=rzjkd(*&bHcoXkwl2f1d_cKXMJmnG>< zzkToCF^kFk(8Q?u!CvzNx4+oFn-AvhtUeSS{?0Pm&E0+B@ysi4Iyc70$N#ReJ9lTn zYr){Z&oz!F3HtMx?)LNd|0uct{O31sc;?G&J=Wv)_|YS!@6Qcuraq`FEoD95A}%f- p-=&lu)F7h3>cNOi)vaNwXV|do8uL`yN5-Hm=;`X`vd$@?2>>o>z|H^w literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/menu/link_below.png b/Telegram/Resources/icons/menu/link_below.png new file mode 100644 index 0000000000000000000000000000000000000000..315150fa66007626819a4b93a9529b2ed6a181f6 GIT binary patch literal 454 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1SIoCSFHz9jKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uv49!D1}S`GTDlgf%)rydF~maf z?PUKx7YC7Jy*zpff*aFUHZL{a(PqIg_g=K{#zH3X1B`1r_eSh+_CB-|6=3kpE{?FycF7gPgaRM__i$ZONGt5@4vlR z3S7&!b1ydFDR)(wu)_Vrqh4h@k@7SaJ z9zWPw7W@2nUF`KjnfrO>zL)v>-Y$!rc6Jlbs^-$YasJCMuj}Dx3ZJ#C_WonF&J$19 bckW}{cC9z2qsQttC=5Ma{an^LB{Ts5(^a$1 literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/menu/link_below@2x.png b/Telegram/Resources/icons/menu/link_below@2x.png new file mode 100644 index 0000000000000000000000000000000000000000..f30fe99b492a0ff5e4438bc3ddf656f3bc98f18f GIT binary patch literal 761 zcmeAS@N?(olHy`uVBq!ia0vp^1|ZDA1SD@Hz16gOaCzcW3a9k^YV&}h}5>$UKFt)M|G0Q(PMr>C$GD0OjUL| zU;S#I?`NNPJD%;F_q;Yc&G2sVdCUEuXWyS&o%Zf{dqpQ#2N>1_I(#~sBw4lh-s`Vg zQ@yUqv_5=T@S<$@_uqe0*Q9O!`E#E3M2`;}CO)cp{88e^gFQ{p&p-cMWB1(ixSr&b z7bR9ZW6n+1IZ(PYreSh}i=k`CgZ-flyHD5H#p{R(Uy#V(9<4WBd-~}qrZ2z$ZusE<==iPhxI>ObycfU zzU%noeuIDKdfk*8PNf*x81``g=9}xMuJ+>PgQW>|CT}J=hWjiHYVqE7H}B`^3Dp~0 z7?L(dOklp)bwp2cEz|l(0cuYQEav#BD{}T9Pd1RSIB3F|x%Jk`6rTdQ<|8v`DTGdPqR}FQzHY*n(Nsy5_2mfHl0mtmWogj za$NAnjwQ!ysSp=1$fSDP{1W9vcHi9>wKm{nh6&e19>tkHVJkx>tiGGK`f8S(%q+dx zXSc=Z1t$LBcWe3d)8_Ku=(X3*Z*=re+Zwg7SJAH^s+Dn1;)xs+DXpnp%NSZB#JXAg zK6bDaufP6Uc48zF85Q64l+Kg+AG%W+UoT2lkr|n#6gA`6MbbAj}p6u!37?Q#I zHtM{0mZQi!TT^kpP4Qb!i)n3{5GEw0C?x3U(kxK}EO zOux2BVUhf5vvn+jD%zW!-tJ{SRB-W9=AOrUj~1GKzh`{^=f3>3Ig5+g**-M$Ent4Z zVAX)2_8)GvH!%v)x_a!`u`5?Zd<~Y*2wEx9=`wHLydy{WTb=%=eDGX;`OB(*ms-x9 zIdh@qW1rysW1l`5ong#8z9wvSZhrpdYWJ~8}iJjD8 zaQ8`LzBKjRdRfC&r<~VcfB*iyak!kky!`Uz%dM@gH#{sW-L;;vy}f;}_(8k*{gb}D zd86a`{9}bi_12a^-=o{NZ=aUOGrd+$Z`Dc(4weS7&kJ1^U$n5c?mn8tQ)W=UP-xou z=XdkWi}^gQf_z;)XMCL@()u+c;r{N&9i3S}@7;^r8f9x|CnqJ9#1N)6^62Db z@gunCt@*=0hI0Mu*RMC1cicGb^wV31Rd#RQvW4aNv(0O%Q^ozech|04H_1D~wV=RJ&++QBXUk6T{5W`U=aJ8!jT8TW`0yc9I^^JN z|34W8j`L>Ee*LG9XO8907(Kn6mCaE)(~ci^Hwrt%wxY;t?jFv9Bkk*Zi+1WvVacty zdE#L~!I@j~87o{{vUx%#S}nF`u}CwV>GS;g^9_-A@83Uccg}FK%7p+2&q?Bw7s1lI bQNaUyfu&o^ub%I^49a$%u6{1-oD!Ml4mk+4?JW>++32n8^yWwdhuNdofJ0`pxrh_y^mT0havTae`~Q&O_Jy4H&F z`*%-Coq54|ywJSWC+*+=`-Np?K`Z~K>7Q&en(4DJz~fkH%FdX)?a_ZVEw)DGnn=y{ zTmHSh%to$}QA~wnqJ<3K-njFHGF?>(3=MC;S4Va`dz^0f2s{u_^6ZlGx%)Y0Q@v8n zX1|hWk|JK!Sj0m`1Vs-Xu(W?0MT)yRw?tx2A79KY_>$bQtz;6Ef zu+>XquCwy6KB}=(PddW+{mp5n%_m_8_OxYB-e)5UsEep2ZetR(C!poAd)uBPH zCxV^6R>iKYnD_l#>Y{7u8$z@Ut+vFtTnO9}qBYm=vQ*810EJaM0t78CXz|L6>Xq2Y zt>*Y^HUIpn{{LJ~cfJ%@u(-q@GSHcRy6})~yuhPbhIeCQPup^einn+e=Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91FrWhf1ONa40RR91FaQ7m0NXcg3;+NFFG)l}R9Fe^Sk0~>K@?^T3sy+j zSP(x;8{*zX!rp=>@Bl($>oo)siS>O14N_si7eq;7RH)w(le zq86P~r_TA#*QZYXbel}i_RPS4mI1TO`}ll5zu)h6yJd`(Hs|wsyJ;IDww>7)%!Fu2~un`}0l n*=(lwr|0!B&(UWF9y9}AY-UF=+Zal<00000NkvXXu0mjfq-dU9 literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/menu/link_enlarge@3x.png b/Telegram/Resources/icons/menu/link_enlarge@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..78b3f137be2fcaa8106e68e7bd49fdf4d431e498 GIT binary patch literal 1378 zcmV-o1)chdP)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91NT34%1ONa40RR91NB{r;0FW_8?*IS<%t=H+RA>e5n!7JPO%%s}F13&l zArhA$Arum&0u|Ay1@S*9Bnp3kzkw)(PNF~*fLmX^xMM@L6pU0oj^A5s!VVCwa``uh5so}Sj# zgc&r;KBz1X(E#aFclh zSonRCO;#*~GlaL0y`I1jNWcp@u$)(KZ*MWLD-&X107h{Go~fB%IkAP zfDvGTG$}7ORS+>r6+64gR)mg@j^5th;$owAmh|T4=KlV^TODA=#>P}RAWZ?6ap>ym zY8jOCO62H5TU*=S-kuLDrGjv=v$NC9O$S4;YQkfTP&gl@52vum(FLX}BP+CUQZcJ; zbvhVAaCZY$VkD-=?D({)e~9vxm6g-e(;yu^`RibGkd6V3uIOlI@s(|j0IjB`M#oL` zw79rfSy^dIQ3Aw(&ic8%y%i2kO-=Lj^A=e#ve6Yq>u(Fq&CT1}+pMc6yStlc&E!g^3n<`21$mPC##E#3tOy` zAr=Fx1c((C6|JtW>bnIVsLvHqqRg8vOJP7EZdW8bY;0^);MfBltSG;`yHjzAih~2v za5sya7?IxW>?}C0uCCmyDCg|vTg}MG2qC3A0(KL~x@2NvLeidwhK8*B`*tA0#wUH7 z7%KrIzyN7#m&`e)N9ZPG5zFIt#fWf&cmG{t_?w>B1&0;AWh7$c!o$PErq5uUSLf&F z&(F^@Gc(bFS{otb=E1J@`T5B@J~=sYf0u>T{r$bHa*Oj8aPtU1W902BQ*3Q*C2Q0z z>WD4a*-0+-1~JItiRt;TE<0Fp3J(kn*oxVMTO>R&PaSSno~N*9U%Q1iiRBI}Y-EjC zPO-8^tiHb9k>Mxhf#T10LaK#@1^LG08MBMN*aSPSm}{&spPd;~^T3z0(a}-zD9Hwp z$*;&nVw)&YWRn>4wz07xLo0!-k^Cx$4rrnwf#~^(JYe2VT*3h@Lq!*KFh0IuTw?^U z0>U%WFhOrY_Vsb{^(WjOi# z6q|r*0A%z)BLV*k_Q`y??3{Uxc~Vu^)A`Lspme$fK|0_R)q-1IH#ga7~l07*qoM6N<$f|5>qkpKVy literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/menu/link_shrink.png b/Telegram/Resources/icons/menu/link_shrink.png new file mode 100644 index 0000000000000000000000000000000000000000..48bf8f0350b84caed6229d1fb001c04d17be92ad GIT binary patch literal 542 zcmeAS@N?(olHy`uVBq!ia0vp^5+KaM1SIoCSFHz9jKx9jP7LeL$-D$|Tv8)E(|mmy zw18|52FCVG1{RPKAeI7R1_tH@j10^`nh_+nfC(-uv49!D1}S`GTDlgfti#jAF~maf z>=eVkrT~GqyJwF%Nn2@b*ksUnu7WksA$5&KQ)~N%%?r0oj4oj0&R^JCa>PZ6ZPV}6 zcom)e5H9oG>n~J({`Y@=<>A>cOa9%ix-9(a`|oYJum7DYwvajZym+f<&&P^Ack@nf z`ct!`YY_um#DoJ!9p^n?ef3nK%%rLf3=F$t^frk(T1;#9h&vE4OZ~`mx0Woqn)kc! zzDqC&aG&>_x7|7CK!C!(1wC%cr!IZDr*QdY$@beDXP-^G{#sNQB&BubH}9Vp^Lrvz zthxSLf#Z?IwTo+87D%=&3|XXcDfGh@p;uq4uDqzQ(G%l-7jbpt__*%rRSjS(C?kZp?QMr)8Ny=eMlr-gPusRHRkv?f2g&Q#Qru z>7G6mX1vd$@?2>|oT;Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91FrWhf1ONa40RR91FaQ7m0NXcg3;+NFNl8ROR9Fe^Sg~pQ;; zz+^J6o4arKy@ZEbEO+kQIp@rs*_qifnO4s#1OHhD%#{9kJf5AM9f!j~30{nu&*#J8 z@cH?<*Xu3TYVfSDucy=LR;vX>Lmof@5U?6V@KB%6*KW5B(IJ5V7T}ynGL(nR@Aud1 zbv8zgMx$6PHk(bP9neyHO3`dK+wJyXFo^VoLLoF63KD@UYYATwGj;P7coL z#M)2x$;k=R?sB<4RS*g{H#cZoC=_^XI2<02$8bUucftTTV~NFLq93-LAzqCJ+$I`s zw;Pe{4FhVb)vC>An@lFDR7wQl;8+nvKkTJ~q&TfbQB5Qgxx2d~BK#FWlA2nrMpT0^ z;{`dLPCin|jV3h^WTk5-Mjjm)YGg{r&yv`vcF*%S%3= zAB{$oE*Y7j*=)urq3QVeSfuZEyVuv(qGy?Hq@eTj^UKRii^VdXPDMUss8Xqj9u?b2 zK{&DO@9(RSQL2pp$|$TVG1LrUpTcnPRhS`S7GvIIG8ydNDjb@ssDh%=XgnTQguc4E z(mzrhnJTDUF7NK{@(f}1W9tooFpD{yeuF9qt4KDRWqfRBVCxOu(l@13ljhEe`_%32 ztxo#I=Gp{_YOpi(`~5{kogNK>BsE%hO`=e$Ae=m_TL}{ zeLw3*5d#0&uk_j3nL<7mUEh1zApaIIeLw3uhHLtk3#-Ku`|x1wFrU~QXJ4t#H=qEh zel4UtWFMm5EvyB&6~L;)7c?nAy@+n$u<-Qsr1#QOon}?L%D@lJz%NxG2?^=)f^`4@ N002ovPDHLkV1nDxxUT>J literal 0 HcmV?d00001 diff --git a/Telegram/Resources/icons/menu/link_shrink@3x.png b/Telegram/Resources/icons/menu/link_shrink@3x.png new file mode 100644 index 0000000000000000000000000000000000000000..dfb66a523c8929f2e11c4f1e1b5e65266b4c7f12 GIT binary patch literal 1324 zcmV+{1=IS8P)Px#L}ge>W=%~1DgXcg2mk?xX#fNO00031000^Q000001E2u_0{{R30RRC20H6W@ z1ONa40RR91NT34%1ONa40RR91NB{r;0FW_8?*ISe5TDvbbK@>+cA`ucK zG$d{$3av_`Lg!KV4$t6NG9^WsSd?#ae zW*;-Nv-f`AZZ$i5=A7T}oHMiYs;Eex)B~vpQV*maNIg)#9;noV-qzOE)z#I~($dt_ zR9UI1#K-ja_xID&)5F8V<>lq=?X8cbolgx74RdpIXJ=|-A(FVUS77gw)Xe; zZ*FeT6Tp!^*(#vlHa0f4x3>=r3=9no)z{aP=JWIO-rnBV*H^01DIoNGtUfJyKgd7#^e`tR&Xj+DfAMUs2h-(BI#` zy}dm%Gb5d3c6N52o}R9(tQ;L3NxAW0Fj?BHq!_5xKphK}}7~+uIw{JUTim zNP*Se-5uFQ+ynu<0t^WNq*s8|C?m$Z6N*&rqt?U6wY9aZRVI_+n}gNC!2xB;{r&yM z#s)9I$~+hzq#&szCdkG8>Sfi}*H)}59UWIg`7?KslToc3Q4<@*Q_}<^&mzI_S z#e4)3NX5y?$@%$t8abrkum}9{@ge;bvN8c;K!&*C2?3}2!2&TUD_bjk0vfeoN~|wk2@VgPf!q z2L*uni|a?{yuaL!YW-YX)`#oLJ_g1#!Npm9KA-pVfvazTLH8F3US#8?c7X*w3ioJO z2Q#|B0#E##SB^leG%tzm?(PO&68m4T^|5}56)}IgkA5TW3*j$fh8;1m=O5g*v*Pt^qM^l6oNZ iKuser(data.vuser_id().v); - user->setAccessHash(data.vaccess_hash().v); - return (PeerData*)user; - }, [&](const MTPDinputPeerChat &data) { - return (PeerData*)owner->chat(data.vchat_id().v); - }, [&](const MTPDinputPeerChannel &data) { - const auto channel = owner->channel(data.vchannel_id().v); - channel->setAccessHash(data.vaccess_hash().v); - return (PeerData*)channel; - }, [&](const MTPDinputPeerSelf &data) { - return (PeerData*)owner->session().user(); - }, [&](const auto &data) { - return (PeerData*)nullptr; - }); + const MTPInputPeer &input) { + const auto peer = Data::PeerFromInputMTP(owner, input); return peer ? owner->history(peer).get() : nullptr; }) | ranges::views::filter([](History *history) { return history != nullptr; diff --git a/Telegram/SourceFiles/data/data_drafts.cpp b/Telegram/SourceFiles/data/data_drafts.cpp index 50cad31fc..adf92511b 100644 --- a/Telegram/SourceFiles/data/data_drafts.cpp +++ b/Telegram/SourceFiles/data/data_drafts.cpp @@ -81,12 +81,10 @@ void ApplyPeerCloudDraft( session, draft.ventities().value_or_empty())) }; - const auto reply = draft.vreply_to() - ? ReplyFieldsFromMTP(history, *draft.vreply_to()) - : ReplyFields(); - const auto replyPeerId = reply.externalPeerId - ? reply.externalPeerId - : peerId; + auto replyTo = draft.vreply_to() + ? ReplyToFromMTP(history, *draft.vreply_to()) + : FullReplyTo(); + replyTo.topicRootId = topicRootId; auto webpage = WebPageDraft{ .invert = draft.is_invert_media(), .removed = draft.is_no_webpage(), @@ -106,14 +104,7 @@ void ApplyPeerCloudDraft( } auto cloudDraft = std::make_unique( textWithTags, - FullReplyTo{ - .messageId = FullMsgId(replyPeerId, reply.messageId), - .quote = reply.quote, - .storyId = (reply.storyId - ? FullStoryId{ replyPeerId, reply.storyId } - : FullStoryId()), - .topicRootId = topicRootId, - }, + replyTo, MessageCursor(Ui::kQFixedMax, Ui::kQFixedMax, Ui::kQFixedMax), std::move(webpage)); cloudDraft->date = date; diff --git a/Telegram/SourceFiles/data/data_peer.cpp b/Telegram/SourceFiles/data/data_peer.cpp index edda209ad..780b6c571 100644 --- a/Telegram/SourceFiles/data/data_peer.cpp +++ b/Telegram/SourceFiles/data/data_peer.cpp @@ -126,6 +126,40 @@ AllowedReactions Parse(const MTPChatReactions &value) { }); } +PeerData *PeerFromInputMTP( + not_null owner, + const MTPInputPeer &input) { + return input.match([&](const MTPDinputPeerUser &data) { + const auto user = owner->user(data.vuser_id().v); + user->setAccessHash(data.vaccess_hash().v); + return (PeerData*)user; + }, [&](const MTPDinputPeerChat &data) { + return (PeerData*)owner->chat(data.vchat_id().v); + }, [&](const MTPDinputPeerChannel &data) { + const auto channel = owner->channel(data.vchannel_id().v); + channel->setAccessHash(data.vaccess_hash().v); + return (PeerData*)channel; + }, [&](const MTPDinputPeerSelf &data) { + return (PeerData*)owner->session().user(); + }, [&](const auto &data) { + return (PeerData*)nullptr; + }); +} + +UserData *UserFromInputMTP( + not_null owner, + const MTPInputUser &input) { + return input.match([&](const MTPDinputUser &data) { + const auto user = owner->user(data.vuser_id().v); + user->setAccessHash(data.vaccess_hash().v); + return user.get(); + }, [&](const MTPDinputUserSelf &data) { + return owner->session().user().get(); + }, [](const auto &data) { + return (UserData*)nullptr; + }); +} + } // namespace Data PeerClickHandler::PeerClickHandler(not_null peer) diff --git a/Telegram/SourceFiles/data/data_peer.h b/Telegram/SourceFiles/data/data_peer.h index 33a772741..894045fdd 100644 --- a/Telegram/SourceFiles/data/data_peer.h +++ b/Telegram/SourceFiles/data/data_peer.h @@ -116,6 +116,12 @@ bool operator<(const AllowedReactions &a, const AllowedReactions &b); bool operator==(const AllowedReactions &a, const AllowedReactions &b); [[nodiscard]] AllowedReactions Parse(const MTPChatReactions &value); +[[nodiscard]] PeerData *PeerFromInputMTP( + not_null owner, + const MTPInputPeer &input); +[[nodiscard]] UserData *UserFromInputMTP( + not_null owner, + const MTPInputUser &input); } // namespace Data diff --git a/Telegram/SourceFiles/history/history_inner_widget.cpp b/Telegram/SourceFiles/history/history_inner_widget.cpp index c1eb6cf98..c6440fce3 100644 --- a/Telegram/SourceFiles/history/history_inner_widget.cpp +++ b/Telegram/SourceFiles/history/history_inner_widget.cpp @@ -2216,35 +2216,6 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { return; } const auto itemId = item->fullId(); - const auto canSendReply = [&] { - const auto peer = item->history()->peer; - const auto topic = item->topic(); - return topic - ? Data::CanSendAnything(topic) - : (Data::CanSendAnything(peer) - && (!peer->isChannel() || peer->asChannel()->amIn())); - }(); - const auto canReply = canSendReply || [&] { - const auto peer = item->history()->peer; - if (const auto chat = peer->asChat()) { - return !chat->isForbidden(); - } else if (const auto channel = peer->asChannel()) { - return !channel->isForbidden(); - } - return true; - }(); - if (canReply) { - const auto quote = selectedQuote(item); - _menu->addAction(tr::lng_context_reply_msg(tr::now), [=] { - if (canSendReply) { - _widget->replyToMessage({ itemId, quote }); - } else { - HistoryView::Controls::ShowReplyToChatBox( - controller->uiShow(), - { itemId, quote }); - } - }, &st::menuIconReply); - } const auto repliesCount = item->repliesCount(); const auto withReplies = (repliesCount > 0); const auto topicRootId = item->history()->isForum() @@ -2408,6 +2379,45 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { } }; + const auto addReplyAction = [&](HistoryItem *item) { + if (!item) { + return; + } + const auto canSendReply = [&] { + const auto peer = item->history()->peer; + const auto topic = item->topic(); + return topic + ? Data::CanSendAnything(topic) + : (Data::CanSendAnything(peer) + && (!peer->isChannel() || peer->asChannel()->amIn())); + }(); + const auto canReply = canSendReply || [&] { + const auto peer = item->history()->peer; + if (const auto chat = peer->asChat()) { + return !chat->isForbidden(); + } else if (const auto channel = peer->asChannel()) { + return !channel->isForbidden(); + } + return true; + }(); + if (canReply) { + const auto itemId = item->fullId(); + const auto quote = selectedQuote(item); + const auto text = quote.empty() + ? tr::lng_context_reply_msg(tr::now) + : tr::lng_context_quote_and_reply(tr::now); + _menu->addAction(text, [=] { + if (canSendReply) { + _widget->replyToMessage({ itemId, quote }); + } else { + HistoryView::Controls::ShowReplyToChatBox( + controller->uiShow(), + { itemId, quote }); + } + }, &st::menuIconReply); + } + }; + const auto lnkPhoto = link ? reinterpret_cast( link->property(kPhotoLinkMediaProperty).toULongLong()) @@ -2419,6 +2429,8 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { if (lnkPhoto || lnkDocument) { const auto item = _dragStateItem; const auto itemId = item ? item->fullId() : FullMsgId(); + addReplyAction(item); + if (isUponSelected > 0) { const auto selectedText = getSelectedText(); if (!hasCopyRestrictionForSelected() @@ -2529,6 +2541,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { : QString(); if (isUponSelected > 0) { + addReplyAction(item); const auto selectedText = getSelectedText(); if (!hasCopyRestrictionForSelected() && !selectedText.empty()) { _menu->addAction( @@ -2551,6 +2564,7 @@ void HistoryInner::showContextMenu(QContextMenuEvent *e, bool showFromTouch) { } addItemActions(item, item); } else { + addReplyAction(item); addItemActions(item, albumPartItem); if (item && !isUponSelected) { const auto media = (view ? view->media() : nullptr); diff --git a/Telegram/SourceFiles/history/history_item_components.cpp b/Telegram/SourceFiles/history/history_item_components.cpp index a21b77b58..1528269e7 100644 --- a/Telegram/SourceFiles/history/history_item_components.cpp +++ b/Telegram/SourceFiles/history/history_item_components.cpp @@ -435,6 +435,42 @@ ReplyFields ReplyFieldsFromMTP( }); } +FullReplyTo ReplyToFromMTP( + not_null history, + const MTPInputReplyTo &reply) { + return reply.match([&](const MTPDinputReplyToMessage &data) { + auto result = FullReplyTo{ + .messageId = { history->peer->id, data.vreply_to_msg_id().v }, + }; + if (const auto peer = data.vreply_to_peer_id()) { + const auto parsed = Data::PeerFromInputMTP( + &history->owner(), + *peer); + if (!parsed) { + return FullReplyTo(); + } + result.messageId.peer = parsed->id; + } + result.topicRootId = data.vtop_msg_id().value_or_empty(); + result.quote = TextWithEntities{ + qs(data.vquote_text().value_or_empty()), + Api::EntitiesFromMTP( + &history->session(), + data.vquote_entities().value_or_empty()), + }; + return result; + }, [&](const MTPDinputReplyToStory &data) { + if (const auto parsed = Data::UserFromInputMTP( + &history->owner(), + data.vuser_id())) { + return FullReplyTo{ + .storyId = { parsed->id, data.vstory_id().v }, + }; + } + return FullReplyTo(); + }); +} + HistoryMessageReply::HistoryMessageReply() = default; HistoryMessageReply &HistoryMessageReply::operator=( diff --git a/Telegram/SourceFiles/history/history_item_components.h b/Telegram/SourceFiles/history/history_item_components.h index 79b78d6d7..c3bf23770 100644 --- a/Telegram/SourceFiles/history/history_item_components.h +++ b/Telegram/SourceFiles/history/history_item_components.h @@ -245,6 +245,10 @@ struct ReplyFields { not_null history, const MTPMessageReplyHeader &reply); +[[nodiscard]] FullReplyTo ReplyToFromMTP( + not_null history, + const MTPInputReplyTo &reply); + struct HistoryMessageReply : public RuntimeComponent { HistoryMessageReply(); diff --git a/Telegram/SourceFiles/history/history_widget.cpp b/Telegram/SourceFiles/history/history_widget.cpp index c3ac82ff9..836c36892 100644 --- a/Telegram/SourceFiles/history/history_widget.cpp +++ b/Telegram/SourceFiles/history/history_widget.cpp @@ -6237,7 +6237,11 @@ void HistoryWidget::mousePressEvent(QMouseEvent *e) { } } else if (const auto reply = replyTo()) { const auto done = [=](FullReplyTo replyTo) { - replyToMessage(replyTo); + if (replyTo) { + replyToMessage(replyTo); + } else { + cancelReply(); + } }; const auto highlight = [=] { controller()->showPeerHistory( diff --git a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp index 098840e8a..c94e0fa10 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_compose_controls.cpp @@ -626,7 +626,11 @@ void FieldHeader::init() { const auto history = _history; const auto topicRootId = _topicRootId; const auto done = [=](FullReplyTo replyTo) { - replyToMessage(replyTo); + if (replyTo) { + replyToMessage(replyTo); + } else { + _replyCancelled.fire({}); + } }; const auto clearOldReplyTo = [=, id = reply.messageId] { ClearDraftReplyTo(history, topicRootId, id); diff --git a/Telegram/SourceFiles/history/view/controls/history_view_reply_options.cpp b/Telegram/SourceFiles/history/view/controls/history_view_reply_options.cpp index bd2898705..0eb6f8aeb 100644 --- a/Telegram/SourceFiles/history/view/controls/history_view_reply_options.cpp +++ b/Telegram/SourceFiles/history/view/controls/history_view_reply_options.cpp @@ -118,9 +118,7 @@ private: bool selectionStartAfterSymbol = false; }; - const auto preview = box->addRow( - object_ptr(box), - QMargins(0, 0, 0, st::settingsThemesTopSkip)); + const auto preview = box->addRow(object_ptr(box), {}); const auto state = preview->lifetime().make_state(); state->theme = DefaultThemeOn(preview->lifetime()); @@ -246,14 +244,17 @@ private: preview->resize(width, height); }, preview->lifetime()); - preview->paintRequest() | rpl::start_with_next([=](QRect clip) { + box->setAttribute(Qt::WA_OpaquePaintEvent, false); + box->paintRequest() | rpl::start_with_next([=](QRect clip) { Window::SectionWidget::PaintBackground( state->theme.get(), - preview, - preview->window()->height(), + box, + box->window()->height(), 0, clip); + }, box->lifetime()); + preview->paintRequest() | rpl::start_with_next([=](QRect clip) { auto p = Painter(preview); auto hq = PainterHighQualityEnabler(p); p.translate(state->position); @@ -366,7 +367,7 @@ void ShowReplyToChatBox( private: void prepareViewHook() override { - delegate()->peerListSetTitle(rpl::single(u"Reply in..."_q)); + delegate()->peerListSetTitle(tr::lng_reply_in_another_title()); } rpl::event_stream _singleChosen; @@ -382,7 +383,10 @@ void ShowReplyToChatBox( const auto state = [&] { auto controller = std::make_unique(session); const auto controllerRaw = controller.get(); - auto box = Box(std::move(controller), nullptr); + auto box = Box(std::move(controller), [=]( + not_null box) { + box->addButton(tr::lng_cancel(), [=] { box->closeBox(); }); + }); const auto boxRaw = box.data(); show->show(std::move(box)); auto state = State{ boxRaw, controllerRaw }; @@ -440,28 +444,31 @@ void EditReplyOptions( show->show(Box([=](not_null box) { box->setWidth(st::boxWideWidth); - struct State { - rpl::variable quote; + const auto bottom = box->setPinnedToBottomContent( + object_ptr(box)); + const auto addSkip = [&] { + const auto skip = bottom->add(object_ptr( + bottom, + st::settingsPrivacySkipTop)); + skip->paintRequest() | rpl::start_with_next([=](QRect clip) { + QPainter(skip).fillRect(clip, st::boxBg); + }, skip->lifetime()); }; - const auto state = box->lifetime().make_state(); - state->quote = AddQuoteTracker(box, show, item, reply.quote); - box->setTitle(reply.quote.empty() - ? rpl::single(u"Reply to Message"_q) - : rpl::single(u"Update Quote"_q)); + addSkip(); Settings::AddButton( - box->verticalLayout(), - rpl::single(u"Reply in another chat"_q), + bottom, + tr::lng_reply_in_another_chat(), st::settingsButton, - { &st::menuIconReply } + { &st::menuIconReplace } )->setClickedCallback([=] { ShowReplyToChatBox(show, reply, clearOldDraft); }); Settings::AddButton( - box->verticalLayout(), - rpl::single(u"Show message"_q), + bottom, + tr::lng_reply_show_in_chat(), st::settingsButton, { &st::menuIconShowInChat } )->setClickedCallback(highlight); @@ -475,15 +482,38 @@ void EditReplyOptions( }; Settings::AddButton( - box->verticalLayout(), - rpl::single(u"Remove reply"_q), + bottom, + tr::lng_reply_remove(), st::settingsAttentionButtonWithIcon, { &st::menuIconDeleteAttention } )->setClickedCallback([=] { finish({}); }); - box->addButton(rpl::single(u"Apply"_q), [=] { + if (!item->originalText().empty()) { + addSkip(); + Settings::AddDividerText( + bottom, + tr::lng_reply_about_quote()); + } + + struct State { + rpl::variable quote; + }; + const auto state = box->lifetime().make_state(); + state->quote = AddQuoteTracker(box, show, item, reply.quote); + + box->setTitle(reply.quote.empty() + ? tr::lng_reply_options_header() + : tr::lng_reply_options_quote()); + + auto save = state->quote.value( + ) | rpl::map([=](const TextWithEntities "e) { + return quote.empty() + ? tr::lng_settings_save() + : tr::lng_reply_quote_selected(); + }) | rpl::flatten_latest(); + box->addButton(std::move(save), [=] { auto result = reply; result.quote = state->quote.current(); finish(result); diff --git a/Telegram/SourceFiles/mtproto/scheme/api.tl b/Telegram/SourceFiles/mtproto/scheme/api.tl index 2ae1e0463..8a0ff53bf 100644 --- a/Telegram/SourceFiles/mtproto/scheme/api.tl +++ b/Telegram/SourceFiles/mtproto/scheme/api.tl @@ -761,7 +761,7 @@ contacts.topPeers#70b772a8 categories:Vector chats:Vector< contacts.topPeersDisabled#b52c939d = contacts.TopPeers; draftMessageEmpty#1b0c841a flags:# date:flags.0?int = DraftMessage; -draftMessage#db074fa8 flags:# no_webpage:flags.1?true invert_media:flags.6?true reply_to:flags.4?MessageReplyHeader message:string entities:flags.3?Vector media:flags.5?MessageMedia date:int = DraftMessage; +draftMessage#3fccf7ef flags:# no_webpage:flags.1?true invert_media:flags.6?true reply_to:flags.4?InputReplyTo message:string entities:flags.3?Vector media:flags.5?InputMedia date:int = DraftMessage; messages.featuredStickersNotModified#c6dc0c66 count:int = messages.FeaturedStickers; messages.featuredStickers#be382906 flags:# premium:flags.0?true hash:long count:int sets:Vector unread:Vector = messages.FeaturedStickers; diff --git a/Telegram/SourceFiles/ui/menu_icons.style b/Telegram/SourceFiles/ui/menu_icons.style index 59cd81b53..f8885acb6 100644 --- a/Telegram/SourceFiles/ui/menu_icons.style +++ b/Telegram/SourceFiles/ui/menu_icons.style @@ -140,6 +140,11 @@ menuIconPremium: icon {{ "menu/premium", menuIconColor }}; menuIconIpAddress: icon {{ "menu/ip_address", menuIconColor }}; menuIconAddress: icon {{ "menu/payment_address", menuIconColor }}; menuIconShowAll: icon {{ "menu/all_media", menuIconColor }}; +menuIconReplace: icon {{ "chat/input_replace", menuIconColor }}; +menuIconAbove: icon {{ "menu/link_above", menuIconColor }}; +menuIconBelow: icon {{ "menu/link_below", menuIconColor }}; +menuIconEnlarge: icon {{ "menu/link_enlarge", menuIconColor }}; +menuIconShrink: icon {{ "menu/link_shrink", menuIconColor }}; menuIconTTLAny: icon {{ "menu/auto_delete_plain", menuIconColor }}; menuIconTTLAnyTextPosition: point(11px, 22px); diff --git a/Telegram/lib_ui b/Telegram/lib_ui index 71d24af3a..c36559a67 160000 --- a/Telegram/lib_ui +++ b/Telegram/lib_ui @@ -1 +1 @@ -Subproject commit 71d24af3a840d15a6cc0a3a8a1e9cbe77a604739 +Subproject commit c36559a6797f02d8a56a414ac91f9c6fd08b5270