From a0c029c3c10b99b7d1b7bcd42ddaf2911804e639 Mon Sep 17 00:00:00 2001 From: David Baker Date: Wed, 31 Jul 2024 23:23:46 +0100 Subject: [PATCH] Fix alignment of RTL messages (#12837) * Fix alignment of RTL messages Inspired by https://github.com/matrix-org/matrix-react-sdk/pull/5453 but hopefully with the edited marker in the right place. This is a PoC: types aren't correct and the style needs pulling out to a class. Plus it would probably need more visual tests added. If this looks acceptable, I can make these changes. * Fix spacing between text and edited annotation * Update snapshot * Update more snapshots * More snapshots * More more snapshots * Split out style * Fix emotes This will cause them always be right-justified if the display name is rtl. * Add playwright test for ltr/rtl message rendering * Better snapshots * Await on message sending * Better waiting, hopefully * Old snapshot files * Really hopefully fixed screenshots this time * Don't include the message action bar in the screenshots --- playwright/e2e/messages/messages.spec.ts | 113 ++++++++++++++++++ ...basic-message-ltr-ltrdisplayname-linux.png | Bin 0 -> 4055 bytes ...basic-message-ltr-rtldisplayname-linux.png | Bin 0 -> 4061 bytes ...basic-message-rtl-ltrdisplayname-linux.png | Bin 0 -> 4078 bytes ...basic-message-rtl-rtldisplayname-linux.png | Bin 0 -> 4080 bytes ...dited-message-ltr-ltrdisplayname-linux.png | Bin 0 -> 4754 bytes ...dited-message-ltr-rtldisplayname-linux.png | Bin 0 -> 4765 bytes ...dited-message-rtl-ltrdisplayname-linux.png | Bin 0 -> 4965 bytes ...dited-message-rtl-rtldisplayname-linux.png | Bin 0 -> 4967 bytes .../emote-ltr-ltrdisplayname-linux.png | Bin 0 -> 3817 bytes .../emote-ltr-rtldisplayname-linux.png | Bin 0 -> 3983 bytes .../emote-rtl-ltrdisplayname-linux.png | Bin 0 -> 3775 bytes .../emote-rtl-rtldisplayname-linux.png | Bin 0 -> 3582 bytes res/css/views/messages/_MEmoteBody.pcss | 1 + res/css/views/rooms/_EventTile.pcss | 7 +- src/HtmlUtils.tsx | 71 ++++++++--- .../views/messages/EditHistoryMessage.tsx | 2 +- src/components/views/messages/TextualBody.tsx | 30 +++-- test/HtmlUtils-test.tsx | 10 +- .../__snapshots__/TextualBody-test.tsx.snap | 57 +++++---- .../PinnedEventTile-test.tsx.snap | 4 +- .../LayoutSwitcher-test.tsx.snap | 12 +- .../AppearanceUserSettingsTab-test.tsx.snap | 12 +- .../__snapshots__/HTMLExport-test.ts.snap | 2 +- 24 files changed, 242 insertions(+), 79 deletions(-) create mode 100644 playwright/e2e/messages/messages.spec.ts create mode 100644 playwright/snapshots/messages/messages.spec.ts/basic-message-ltr-ltrdisplayname-linux.png create mode 100644 playwright/snapshots/messages/messages.spec.ts/basic-message-ltr-rtldisplayname-linux.png create mode 100644 playwright/snapshots/messages/messages.spec.ts/basic-message-rtl-ltrdisplayname-linux.png create mode 100644 playwright/snapshots/messages/messages.spec.ts/basic-message-rtl-rtldisplayname-linux.png create mode 100644 playwright/snapshots/messages/messages.spec.ts/edited-message-ltr-ltrdisplayname-linux.png create mode 100644 playwright/snapshots/messages/messages.spec.ts/edited-message-ltr-rtldisplayname-linux.png create mode 100644 playwright/snapshots/messages/messages.spec.ts/edited-message-rtl-ltrdisplayname-linux.png create mode 100644 playwright/snapshots/messages/messages.spec.ts/edited-message-rtl-rtldisplayname-linux.png create mode 100644 playwright/snapshots/messages/messages.spec.ts/emote-ltr-ltrdisplayname-linux.png create mode 100644 playwright/snapshots/messages/messages.spec.ts/emote-ltr-rtldisplayname-linux.png create mode 100644 playwright/snapshots/messages/messages.spec.ts/emote-rtl-ltrdisplayname-linux.png create mode 100644 playwright/snapshots/messages/messages.spec.ts/emote-rtl-rtldisplayname-linux.png diff --git a/playwright/e2e/messages/messages.spec.ts b/playwright/e2e/messages/messages.spec.ts new file mode 100644 index 00000000000..bd56d772e8b --- /dev/null +++ b/playwright/e2e/messages/messages.spec.ts @@ -0,0 +1,113 @@ +/* +Copyright 2024 The Matrix.org Foundation C.I.C. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* See readme.md for tips on writing these tests. */ + +import { Locator, Page } from "playwright-core"; + +import { test, expect } from "../../element-web-test"; + +async function sendMessage(page: Page, message: string): Promise { + await page.getByRole("textbox", { name: "Send a message…" }).fill(message); + await page.getByRole("button", { name: "Send message" }).click(); + + const msgTile = await page.locator(".mx_EventTile_last"); + await msgTile.locator(".mx_EventTile_receiptSent").waitFor(); + return msgTile; +} + +async function editMessage(page: Page, message: Locator, newMsg: string): Promise { + const line = message.locator(".mx_EventTile_line"); + await line.hover(); + await line.getByRole("button", { name: "Edit" }).click(); + const editComposer = page.getByRole("textbox", { name: "Edit message" }); + await page.getByLabel("User menu").hover(); // Just to un-hover the message line + await editComposer.fill(newMsg); + await editComposer.press("Enter"); +} + +test.describe("Message rendering", () => { + [ + { direction: "ltr", displayName: "Quentin" }, + { direction: "rtl", displayName: "كوينتين" }, + ].forEach(({ direction, displayName }) => { + test.describe(`with ${direction} display name`, () => { + test.use({ + displayName, + room: async ({ user, app }, use) => { + const roomId = await app.client.createRoom({ name: "Test room" }); + await use({ roomId }); + }, + }); + + test("should render a basic LTR text message", async ({ page, user, app, room }) => { + await page.goto(`#/room/${room.roomId}`); + + const msgTile = await sendMessage(page, "Hello, world!"); + await expect(msgTile).toMatchScreenshot(`basic-message-ltr-${direction}displayname.png`, { + mask: [page.locator(".mx_MessageTimestamp")], + }); + }); + + test("should render an LTR emote", async ({ page, user, app, room }) => { + await page.goto(`#/room/${room.roomId}`); + + const msgTile = await sendMessage(page, "/me lays an egg"); + await expect(msgTile).toMatchScreenshot(`emote-ltr-${direction}displayname.png`); + }); + + test("should render an edited LTR message", async ({ page, user, app, room }) => { + await page.goto(`#/room/${room.roomId}`); + + const msgTile = await sendMessage(page, "Hello, world!"); + + await editMessage(page, msgTile, "Hello, universe!"); + + await expect(msgTile).toMatchScreenshot(`edited-message-ltr-${direction}displayname.png`, { + mask: [page.locator(".mx_MessageTimestamp")], + }); + }); + + test("should render a basic RTL text message", async ({ page, user, app, room }) => { + await page.goto(`#/room/${room.roomId}`); + + const msgTile = await sendMessage(page, "مرحبا بالعالم!"); + await expect(msgTile).toMatchScreenshot(`basic-message-rtl-${direction}displayname.png`, { + mask: [page.locator(".mx_MessageTimestamp")], + }); + }); + + test("should render an RTL emote", async ({ page, user, app, room }) => { + await page.goto(`#/room/${room.roomId}`); + + const msgTile = await sendMessage(page, "/me يضع بيضة"); + await expect(msgTile).toMatchScreenshot(`emote-rtl-${direction}displayname.png`); + }); + + test("should render an edited RTL message", async ({ page, user, app, room }) => { + await page.goto(`#/room/${room.roomId}`); + + const msgTile = await sendMessage(page, "مرحبا بالعالم!"); + + await editMessage(page, msgTile, "مرحبا بالكون!"); + + await expect(msgTile).toMatchScreenshot(`edited-message-rtl-${direction}displayname.png`, { + mask: [page.locator(".mx_MessageTimestamp")], + }); + }); + }); + }); +}); diff --git a/playwright/snapshots/messages/messages.spec.ts/basic-message-ltr-ltrdisplayname-linux.png b/playwright/snapshots/messages/messages.spec.ts/basic-message-ltr-ltrdisplayname-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..fe9244369483ce7e86ac4a6aeaa534c0da5b2641 GIT binary patch literal 4055 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 Yr7mRQ=1SqjC$gA^sy4V%`E|(u0BybW{Qv*} literal 0 HcmV?d00001 diff --git a/playwright/snapshots/messages/messages.spec.ts/basic-message-rtl-rtldisplayname-linux.png b/playwright/snapshots/messages/messages.spec.ts/basic-message-rtl-rtldisplayname-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..e9aded5a5fbd65833ada283947350c84f7d271b6 GIT binary patch literal 4080 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 Q(*XcRdgh?gdk>%f7sbQWC;$Ke literal 0 HcmV?d00001 diff --git a/playwright/snapshots/messages/messages.spec.ts/edited-message-ltr-ltrdisplayname-linux.png b/playwright/snapshots/messages/messages.spec.ts/edited-message-ltr-ltrdisplayname-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..1e29c40c7347dd46e3b726bed94a30c55c768f3f GIT binary patch literal 4754 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 E0M$jhlK=n! literal 0 HcmV?d00001 diff --git a/playwright/snapshots/messages/messages.spec.ts/edited-message-rtl-rtldisplayname-linux.png b/playwright/snapshots/messages/messages.spec.ts/edited-message-rtl-rtldisplayname-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..bec538f32dafb16f93d000f8e0c1f5f4f942e176 GIT binary patch literal 4967 zcmbtYX&_W#_g6|K6oq78qKqv=mMq1fWQnn5jIm8*EM?!xzAO7OD1~GT4YF4Db&NH8 zNP}UljmC`epXvR7dcVG3?s@Kgo_l`hIrl8T`@}sq&|zl0&PYc`$NcaC$e50fUYra3{?5X zdZh3aRes<+aHI;ljkEvLba5UdX-6D~zX4xtKUmvcEH*WC{y5+d>bx^ypNE4qWj6=R zHYcK{aKjs6&NN(Q^=K1uQ?;fx?aRl(#(QrOY&Au#a&la47h?=5K@wy4N>$^}P}i+# zq;H|$8#nDi0{%8dZWtG&mQDW-7&AA#re;qUfvLYvQ`W==C)HhSK4F9f8bzIYTCvaF z;1tPtm-Z37^d%1+*=i1cq<#PhHkk5t97ZhNM;yz^-A4<$Lo#d?F{ zCBOc2qTYczLAR!CxrWAzsWToEG-hKi9236JcW%~WX>e-?SN}ME55T;>By8y!D)#5O zOin{^Kk`K1rPf-!_}!zTNN*wb0Tc7kd8vYSQ3~9g_ELU)5k+FD6wtp|dCUF>ICR{~ z7d?$fyDzJi5s%lBCe1%2JL9xs-fc7I@T(9aK7p}7m=7&}M#_4F)hbPNG%Co5fFg6O zWayRWqJ79YC+|fa!1vPr7~hJ!!KTm5%n(7=A+VAE7+3@s#PoIO(}o?%G;L`nRSweEiQ&I>4Y^;g(1PZTF$}-6DTqb1djp-l=07LD2UYA!nnV>s^u;}5mMB^R}Zn^AZKin zMI&P0r%tK>E03+zcuYcGoML76kcF>1SvRKo9vVe4`a6K(xD+e2_=j4QjEuZp!J|Ia z>!de=HvLY`#dQq2BBL-nJnCPl(%oD`|M-2>zuCTkEj8r1<9a1q( zO;9kAaxD*PI=+;)d(IFU{Cha!Hr@>MnebD-#v(wyG&~lMHF;1hl9Aey!qzti-^WV` ziA$`qV#4n=@D?Tu7O9V3VkzuS);_@IKM61%Mr2REBplp zy+T4y5EH*v+&TFu9EE)X(a{W=le79*b|CD za-QM#&HOA>JG@?aV9^fwW_1CC+weRb7o?V3{h66&+LAn4*rtq=b>1+O^l_*lSZ~(E z-BVY|8|3h;WXcczlrJXM%S-NBr_A_R4t~YPuJ`Jr_iS}@HEKW-uNfn$?wFbVZnMp}UBhR#6{1KrW~8exU!7YH zLrk$R8*=L>1Ew%_4O2lWFRws7#uEH8PbpQH>p z^Rs)LQ&M%McqEjsNMYHGHZV_G0x$|BaP~|tpVU*T0X&;_qSA&N5u@&eQmZ!8tNynj z9AEafzIl@KPiKPE2eCX5ply9SxS8`3&6dbH%HZ@s^0PN!*!&>ilwAX*s%!K2{(=lW z7}~HKe0}m!u@`A>QA|B$)pSxmFRiS4OJ$}iU;Je17p9(TdeuF|-{-!KIskawvb=F@ z%jF$}aS0XUoW*0od&||oA-U`98GD(-JnsckHZe|_PXnTgReZ(j%6;R3wfzw*z;Z;? zLPX_LIb~|cqzg;#c%{3#fZ*DNekVe+R$bxO*A$uRZr96>+j+0-pJ|D2nmZ`!7pe;X zM&?XmB>Pz9A>884#h5Jp3Cnecu)Ixp;PPE{)yz!B3yaXK=PLNcW_d@V5+1VjuDV=T zoCYyzJYG0qzTeK*R9@0j57i!3z(7OoFMwgq&{|dLr2xv8^cGnIXf+?hO7wK%iv|;= ziI=g>=Gz>3pK_906T6vFH4SzRh+?WPy7-$L=-4$kI|BZR7<=?h1*VA1$iXd~>*6Gc zHl3e8M^bi>D;Uc53vYMrPyARj)c;1)Q&2UmPQ~z7=+49vyMGd7hS+VOUg^I^r?Z zEKp2szwn?(>ymCfU;5?O#dSIGMZWq7i8)b4uIvq;du9J%!{h%^0y?i()E-Ie4q=>S z++}EXyX;U_(YbQbTjSsR{#YCbZ4gp3|82&)S0iU?mr5;GaD9L1#34l z?c!B$i}G~6Fn%$*urEtqVs3U zLY^>NT*_IUha#zF#ac98RvrBr!o}j#+U$+^lcAKbkPm>wDrLQy8L_mS-wc?2Ki~h@ z)pym@%Oi@YS*K$GCm4(ZPr)uGGAU5{EC3HFtB=;lu-pJ>;nHfvF8bvvAsa4DC z5!YUV$=p6xjSj0X^B1L$?U-4ETgZ7zK^Ckcjj{7*=h)VLR#C##@b59+sG{ zQCGr=@0Bd+()7&C8=ZyTK0d~_0)F3g2LSsQ`9sMR$lhsjr8%lOeIW~hEGHXEgHV{^ zG^dRng_G2JJ7$@+t9845Ux-n-HtV(*f8u9mns$JW@G<)+t*$(?>K~tu_7j^g zR9MZ|LvlW z@NqI$#+Tt8(eW78?k^^Hq{8|Pf$(Q~u8(#)$}^#(g?r2O#yMwtde!N@!dp|=VW#m3 z`1+a?`aCi{GbAR~xT<&vsTS2`w^3^`R@zpg2&v<`DstO_+vG*LX*pTX%P*{*pVidd z+K19FJ?`9LM56TJczBjP9Dg&g#%2S8lh)6-K}sHlGX$Ftey z!}V8b92^|XyVUM>^QycWZ~%MpyRZ; zwAh5>#&aubWSrT&^C5!cur0<7hd_w(rJcAVF2-7LQ? z^=9fMU1Q_%DTy`*TxPr?1yu_XN5*Qi?4Q4oQdVAGU0I$G|K-hF%t0u!zTT{ZN1OI7 zZ&iQTv~`=bd(Fp(KkGlO$IB};gK~r!7#O6{0fA$wqsBtIdb-zFm1LD=4+b(|NHt#3 z47Gi9;NY4OwdkDq``*{;8VmPtu@thav8YYa6RpeaLBwKro&R{{eIbyEGS=@>KqikL zU%M&?5E62pos`_=Tplb`?GCA`0(lXu0ktX9(q?~C|GO{1ww|O@pvb;`nrMF+a>V>c7D$xEvIi1Ynlk+5H(>0J40}5SS zYy2zE-LQN1bl|MDry~O!=2zGYYAuCTO%FP3oH5u%4?53qpKVopHa0m=&9L9{9!@k@ z^bPi}+q=)&y)Kl3eXGW9Pq%9Nd_(3u8Oy{MhI;5HCdGYd&zpVQq3%B01{U}^wNLye z__j$RGyOft#M-*Xahr0A{)m&46P*hTB~&QjHa4V1MY6NAEi4YwS6_JIeAjl+>Mrw3 zOSeC~c_X7J;zd?0#NzzbDq32CCd?P9E3a{LFE-_~Ub*7v?(U1<6hUA*)vWs4 z`@uUqM*Ji*m7Zil(yb3?QMafqcKore(Qetu+Ug^YwscIx<_~r3(6h-*j`$90`cMkJZ5hX2-p(3!OV0_C76VJ$r znKr}2zTV#6{{B5`EvbFh#b56dus>bb0M*xmPhb{>vLukDWkjz6)cenKBO~{8NIBc! zn^*BF&zFz=flSl=ZMX~nO0X<}S6S_rjg>U61o}W{U_d%iDQjmboLD)77&xitQ}wZ% z8r~`>5cd9z;#V6y@|aK{o{hpT7bPa0wC?|m(BfymdbPV7RA2m^N)X!G7J5HL0iATC z`<^QzzbZW4Sl{SI#yPc6Cbts5e;49(6bmH%c86{n7ol&kVaDmS+!dLV)T*mXxn)oNj!C@EtHE}NoPZADA_uUY#@mtLk*}5NE1U~0nLNq8{9vEa)&tM<{~wgzOB6dT_T!x+|yrm*Co*$ z!pRj_Qy}fYeO&3+w zd1l;Ho0{v!fYg3jAqx+c`}7VCV0Zmix``D;0^)9SW_1&8`ESsD&}LV7kD*EoOYNHN zWL->-g@lyUEkJ-(s)z7ArtR=*D8FRoBy=~0mb5>kltY%M^41#yvh)6UdjBEty{oR? zlz%AwH7>0bzZm*+dGpuG%KRoTy}+f?k4MADgB8dYu^X$`bFZro>GANokiHz;9+?6Q zav#wS1L*#QWB+s5l;xI1(eZ9{{RC1wo6kbTRR zeHb!RgF$vOvJA%heZ2p`_m}57&*$9NeeSbd=iGO+nTh^MK5;${4vv!sccB&>99)_} zTjdxh@Wlpv3IpJXpN0M{4kG!Vc@7T#90TZ0tHAW7QFq%!8#>P)$W5)E@p`9j{Wyi! zYx}IEcjHKk1^!$WEFV_H=Ru*ENEQuk7R91#eB=~}a-2l#8{gk6ezGc2kwax47k z-Lx`&(fb=8d{R9FB)A?KXB519U!)kYfTm zWkL+0Ocin#-1Nj=aQ5(c7%2XU{yN23R`6{zY6-({vz}@LdU%n}K_V5rvN-adm}W%(_1@G5347t*osP zmoIMlySld0hvaAbl#gXL$_9@WUiBLWCsukYIXma%`sEKJ4kMd8_olgKl;@X~mDR0$ zV_(Vdw1JT?gc^IBmzqYzkHh2pWsTx+8yhJ}zq)e5Ew#lmhi`9H`rNrRYhMZvp#sQP zVC&--PDL+3@svsxz0arOyRXP1EG3UND?F^qj5D(p)dHs@zZq{0P$;BI=Vey}DD3A~ zn8meF-%JAGc$Bl&^EYq@ub$~{ysSyO$CwKvFFSjcm=8quYIFLw8ueshW&U?thYp4Y!KrFPj(07jzyT6fgs`VvX=I(y&|X(RH?&Txr|jrTs(tUuONp8-LG18r z_>cQ~6CLVjCa(5;BVTse&CNHJcyDq*iGaFzPd@A-d5FJ%gtStHH}JtraB+hi5|H-j z#Jrj5Y1s=Iv-b3rz`Acbmirs!F1(kNl@a$IBFjI#ew{P8E>>n}WHim&v3my-A1sBu zt0dyXDD@tH7+|#MIC=42Ln!# zW8U-$_F8snshZntST8rfFEcYax%cm&HMDnHr5C(neFr6PFsAHS^|U3=dsyZ|3KT?% zm8{hw#vxJK4vyse>!X_q8}%XnrztE#FUP-yV>wggpQWAU7w-@w3t z2bGvZuryz>r_MHUMm!vx@#fiBo~O~Gkv%>42n0`9k)yibH(CNeN>ugtV;_C!+U#30 zZ-%M}%1#N5C90efJ0p(67c@v(F8qxz(_f-H!c_;TR8Y1&+yryQT_LTP|Jc@bor$g7 z=*j50DZKhSZf@pNVs&-U(9n={(@hZ(2M}GVKCLMCyy@3(U~;-}3j$Xp{2MvKIyl(O ziR&{1m5x7OJI)7^$#E%H-xmX(kNx1Y(>l+jM&Jvdr;KQ7WlZCP=Y>-?_dS`_Nmi9j zy*4P9c)Lt@33s$GtfR&rX8Xv==ZTXK6sjbGxITg{YVE3q^$#{xWwlt&JHLz(3hMfz zx3|qw4h8M)@VNW3jPLI1($LWO;We*_WV4SZCnq;a3rgH?1(_Rrdp~$^ z`=>{fW=h>9HH|_%9xr?>m+E5NshevgI(=NU&&|cr4ci^^1CG4b$lg=dV0z#ZerwXSukq2(UKPz_T4a5k|FY7Uyp5Y%^z3V0YKUe=s(pAK7-aIcN81IqjL_|Fo1tkpe1DQi-$LqSUtPVOd7?#yX-H5YT+GJb z=iHsCo_0`_3*PF=4mXt$^#d8Ax`RK`LOn6i08cJAO7pHU*BW1PtWz z0y^A1y;97Q(9(qXrAj|U^;FN4GP!8!Ie7)aOZ0Gm`e@xp6X?u8>iGY}AA^ncZ(B6% zT)YvU86qI%^WoZhZb?TsqU3dk^&oayxR}Mt_32G9bVUF=9sB6avfgwBUcaELz*;j& zKYY1-d@AW|#mToe^MmiXCe#G>ocMQQ-}Ge?3JZ6GZkUBO^S*qk34shZ8mC=uog92c z*@w1Hq>4#MC_kw9wK6#ZtjdS9%G2?ff`#99>gZj+px>me$Vgc{-bOZ@Jw(K5_Xvtf zh@GNzCg!71MndEYH&a1j;ba;8IBkS|DkfMHHn#y@6t*_b~hXr~Wjl5v# zkrjd5>LmQ%G?;CR=v>-@t$6;qqGXiA{Qoc!1^xuR6% zpdO3QjWvhC7&Sr8j$sYOW4Mf3f7KJ2s$#+-*FtV?)fuN%1_$qu1rBy_<}EhFt%#s( zthOVc99D`(Q<*r)Rh}fC7R1(mt)AewxcjA3JgPp8TW;4HJ$Fi0(2iia)Jy}NG=dVjF8Tm8Yt zJ{jkCW7!?@?T^t|;ra+!vB1lJ2>f01AwGb>*&rhzHFH90UaB74H8h>LnPIfp!<#Xt zSKVEM)Le$dbKlA`v#XxC%$S-=npbzzC9_|*Idyu37k2_F>z6V?H%ny4SRX3O6nLL7 z;t%%fMyCb3tulwKs48M5@$iE2Yi8=0(Hi1C0n5SGpl!Y`Rk@CuL`f~x>(cwU@3Ip6 zo9NxOC|&00PW!LMwAA&$b-B$bDH}SS?loL$4%^uwivk&B2JhSE4g~2A_vjsVa2-PF z_E6fwo54=a@<{o~JBkJn4kMAg?HD98?>a;1`707Cbg)G3cSoz^ZKYxHIj$LSb0cm} zZ>!Qz))e!n!O#6G0cTquyj0zqTUz@3HW!z!Ze|-w1dx1(NB9`~aAJ*g`yr?)P|u^ra)3m&A3 z(M^^&0;^|y6>dQ2(<`O50h3n(CW;H{paRkNProq?qU+cii$`yR%i?MT*dAYHrA@pp zq#x#)9R1gd2z}z#4Z(>S>z8!P=Gc1)vztc9j#hGiZpvjEK5FvPedX80<#X2mIgO0` nuk7QflTm9NJ1ny}7^rZrCtlg1RY$bphyMn8CQ#z7hmrpSV;+3* literal 0 HcmV?d00001 diff --git a/playwright/snapshots/messages/messages.spec.ts/emote-ltr-rtldisplayname-linux.png b/playwright/snapshots/messages/messages.spec.ts/emote-ltr-rtldisplayname-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..04f4e0d1f5a8ce64569dfcbf9e9ba8dbf41a360a GIT binary patch literal 3983 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 ByMq7# literal 0 HcmV?d00001 diff --git a/playwright/snapshots/messages/messages.spec.ts/emote-rtl-ltrdisplayname-linux.png b/playwright/snapshots/messages/messages.spec.ts/emote-rtl-ltrdisplayname-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..ee9d8b8a43e2c7435ab388df74089be9d59077fb GIT binary patch literal 3775 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 literal 0 HcmV?d00001 diff --git a/playwright/snapshots/messages/messages.spec.ts/emote-rtl-rtldisplayname-linux.png b/playwright/snapshots/messages/messages.spec.ts/emote-rtl-rtldisplayname-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..19075ea869fceebcfb56ccb7ef700298f74329a9 GIT binary patch literal 3582 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 } function analyseEvent(content: IContent, highlights: Optional, opts: EventRenderOpts = {}): EventAnalysis { @@ -375,7 +374,61 @@ function analyseEvent(content: IContent, highlights: Optional, opts: E } } -export function bodyToNode(content: IContent, highlights: Optional, opts: EventRenderOpts = {}): ReactNode { +export function bodyToDiv( + content: IContent, + highlights: Optional, + opts: EventRenderOpts = {}, + ref?: React.Ref, +): ReactNode { + const { strippedBody, formattedBody, emojiBodyElements, className } = bodyToNode(content, highlights, opts); + + return formattedBody ? ( +

+ ) : ( +
+ {emojiBodyElements || strippedBody} +
+ ); +} + +export function bodyToSpan( + content: IContent, + highlights: Optional, + opts: EventRenderOpts = {}, + ref?: React.Ref, + includeDir = true, +): ReactNode { + const { strippedBody, formattedBody, emojiBodyElements, className } = bodyToNode(content, highlights, opts); + + return formattedBody ? ( + + ) : ( + + {emojiBodyElements || strippedBody} + + ); +} + +interface BodyToNodeReturn { + strippedBody: string; + formattedBody?: string; + emojiBodyElements: JSX.Element[] | undefined; + className: string; +} + +function bodyToNode(content: IContent, highlights: Optional, opts: EventRenderOpts = {}): BodyToNodeReturn { const eventInfo = analyseEvent(content, highlights, opts); let emojiBody = false; @@ -419,19 +472,7 @@ export function bodyToNode(content: IContent, highlights: Optional, op emojiBodyElements = formatEmojis(eventInfo.strippedBody, false) as JSX.Element[]; } - return formattedBody ? ( - - ) : ( - - {emojiBodyElements || eventInfo.strippedBody} - - ); + return { strippedBody: eventInfo.strippedBody, formattedBody, emojiBodyElements, className }; } /** diff --git a/src/components/views/messages/EditHistoryMessage.tsx b/src/components/views/messages/EditHistoryMessage.tsx index d688650353a..125154c4d9e 100644 --- a/src/components/views/messages/EditHistoryMessage.tsx +++ b/src/components/views/messages/EditHistoryMessage.tsx @@ -172,7 +172,7 @@ export default class EditHistoryMessage extends React.PureComponent { - private readonly contentRef = createRef(); + private readonly contentRef = createRef(); private unmounted = false; private pills: Element[] = []; @@ -566,34 +566,38 @@ export default class TextualBody extends React.Component { } const mxEvent = this.props.mxEvent; const content = mxEvent.getContent(); - let isNotice = false; - let isEmote = false; + const isNotice = content.msgtype === MsgType.Notice; + const isEmote = content.msgtype === MsgType.Emote; + + const willHaveWrapper = + this.props.replacingEventId || this.props.isSeeingThroughMessageHiddenForModeration || isEmote; // only strip reply if this is the original replying event, edits thereafter do not have the fallback const stripReply = !mxEvent.replacingEvent() && !!getParentEventId(mxEvent); - isEmote = content.msgtype === MsgType.Emote; - isNotice = content.msgtype === MsgType.Notice; - let body = HtmlUtils.bodyToNode(content, this.props.highlights, { + + const htmlOpts = { disableBigEmoji: isEmote || !SettingsStore.getValue("TextualBody.enableBigEmoji"), // Part of Replies fallback support stripReplyFallback: stripReply, - ref: this.contentRef, - }); + }; + let body = willHaveWrapper + ? HtmlUtils.bodyToSpan(content, this.props.highlights, htmlOpts, this.contentRef, false) + : HtmlUtils.bodyToDiv(content, this.props.highlights, htmlOpts, this.contentRef); if (this.props.replacingEventId) { body = ( - <> +
{body} {this.renderEditedMarker()} - +
); } if (this.props.isSeeingThroughMessageHiddenForModeration) { body = ( - <> +
{body} {this.renderPendingModerationMarker()} - +
); } @@ -624,7 +628,7 @@ export default class TextualBody extends React.Component { if (isEmote) { return ( -
+
{mxEvent.sender ? mxEvent.sender.name : mxEvent.getSender()} diff --git a/test/HtmlUtils-test.tsx b/test/HtmlUtils-test.tsx index b3bad1813cf..0de866d4520 100644 --- a/test/HtmlUtils-test.tsx +++ b/test/HtmlUtils-test.tsx @@ -19,7 +19,7 @@ import { mocked } from "jest-mock"; import { render, screen } from "@testing-library/react"; import { IContent } from "matrix-js-sdk/src/matrix"; -import { bodyToNode, formatEmojis, topicToHtml } from "../src/HtmlUtils"; +import { bodyToSpan, formatEmojis, topicToHtml } from "../src/HtmlUtils"; import SettingsStore from "../src/settings/SettingsStore"; jest.mock("../src/settings/SettingsStore"); @@ -66,7 +66,7 @@ describe("topicToHtml", () => { describe("bodyToHtml", () => { function getHtml(content: IContent, highlights?: string[]): string { - return (bodyToNode(content, highlights, {}) as ReactElement).props.dangerouslySetInnerHTML.__html; + return (bodyToSpan(content, highlights, {}) as ReactElement).props.dangerouslySetInnerHTML.__html; } it("should apply highlights to HTML messages", () => { @@ -108,14 +108,14 @@ describe("bodyToHtml", () => { }); it("generates big emoji for emoji made of multiple characters", () => { - const { asFragment } = render(bodyToNode({ body: "👨‍👩‍👧‍👦 ↔️ 🇮🇸", msgtype: "m.text" }, [], {}) as ReactElement); + const { asFragment } = render(bodyToSpan({ body: "👨‍👩‍👧‍👦 ↔️ 🇮🇸", msgtype: "m.text" }, [], {}) as ReactElement); expect(asFragment()).toMatchSnapshot(); }); it("should generate big emoji for an emoji-only reply to a message", () => { const { asFragment } = render( - bodyToNode( + bodyToSpan( { "body": "> <@sender1:server> Test\n\n🥰", "format": "org.matrix.custom.html", @@ -139,7 +139,7 @@ describe("bodyToHtml", () => { }); it("does not mistake characters in text presentation mode for emoji", () => { - const { asFragment } = render(bodyToNode({ body: "↔ ❗︎", msgtype: "m.text" }, [], {}) as ReactElement); + const { asFragment } = render(bodyToSpan({ body: "↔ ❗︎", msgtype: "m.text" }, [], {}) as ReactElement); expect(asFragment()).toMatchSnapshot(); }); diff --git a/test/components/views/messages/__snapshots__/TextualBody-test.tsx.snap b/test/components/views/messages/__snapshots__/TextualBody-test.tsx.snap index a9934fb32da..56de44137fc 100644 --- a/test/components/views/messages/__snapshots__/TextualBody-test.tsx.snap +++ b/test/components/views/messages/__snapshots__/TextualBody-test.tsx.snap @@ -1,7 +1,7 @@ // Jest Snapshot v1, https://goo.gl/fbAQLP exports[` renders formatted m.text correctly italics, bold, underline and strikethrough render as expected 1`] = ` - @@ -21,11 +21,11 @@ exports[` renders formatted m.text correctly italics, bold, under u - +
`; exports[` renders formatted m.text correctly linkification is not applied to code blocks 1`] = ` - @@ -62,11 +62,11 @@ exports[` renders formatted m.text correctly linkification is not
-
+
`; exports[` renders formatted m.text correctly pills appear for an MXID permalink 1`] = ` - @@ -105,7 +105,7 @@ exports[` renders formatted m.text correctly pills appear for an - + `; exports[` renders formatted m.text correctly pills appear for event permalinks without a custom label 1`] = ` @@ -113,7 +113,7 @@ exports[` renders formatted m.text correctly pills appear for eve
- @@ -152,7 +152,7 @@ exports[` renders formatted m.text correctly pills appear for eve - +
`; @@ -162,7 +162,7 @@ exports[` renders formatted m.text correctly pills appear for roo
- @@ -202,7 +202,7 @@ exports[` renders formatted m.text correctly pills appear for roo with vias - +
`; @@ -212,7 +212,7 @@ exports[` renders formatted m.text correctly pills do not appear
- @@ -224,13 +224,13 @@ exports[` renders formatted m.text correctly pills do not appear event link with text - +
`; exports[` renders formatted m.text correctly pills do not appear in code blocks 1`] = ` - @@ -266,11 +266,11 @@ exports[` renders formatted m.text correctly pills do not appear - + `; exports[` renders formatted m.text correctly pills get injected correctly into the DOM 1`] = ` - @@ -309,20 +309,20 @@ exports[` renders formatted m.text correctly pills get injected c - + `; exports[` renders formatted m.text correctly renders formatted body without html correctly 1`] = ` - escaped *markdown* - + `; exports[` renders formatted m.text correctly spoilers get injected properly into the DOM 1`] = ` - @@ -346,29 +346,28 @@ exports[` renders formatted m.text correctly spoilers get injecte - + `; exports[` renders m.emote correctly 1`] = ` winks `; exports[` renders m.notice correctly 1`] = ` - this is a notice, probably from a bot - + `; exports[` renders plain-text m.text correctly linkification get applied correctly into the DOM 1`] = ` - @@ -381,7 +380,7 @@ exports[` renders plain-text m.text correctly linkification get a > https://matrix.org/ - + `; exports[` renders plain-text m.text correctly should pillify a permalink to a message in the same room with the label »Message from Member« 1`] = `"Visit Message from Member"`; @@ -389,7 +388,7 @@ exports[` renders plain-text m.text correctly should pillify a pe exports[` renders plain-text m.text correctly should pillify a permalink to an event in another room with the label »Message in Room 2« 1`] = `"Visit Message in Room 2"`; exports[` renders plain-text m.text correctly should pillify a permalink to an unknown message in the same room with the label »Message« 1`] = ` - @@ -411,14 +410,14 @@ exports[` renders plain-text m.text correctly should pillify a pe - + `; exports[` renders plain-text m.text correctly simple message renders as expected 1`] = ` - this is a plaintext message - + `; diff --git a/test/components/views/rooms/__snapshots__/PinnedEventTile-test.tsx.snap b/test/components/views/rooms/__snapshots__/PinnedEventTile-test.tsx.snap index 45b1bf2e3aa..960177a38e5 100644 --- a/test/components/views/rooms/__snapshots__/PinnedEventTile-test.tsx.snap +++ b/test/components/views/rooms/__snapshots__/PinnedEventTile-test.tsx.snap @@ -26,12 +26,12 @@ exports[` should render pinned event 1`] = `
- First pinned message - +
should render 1`] = `
- Hey you. You're the best! - +
should render 1`] = `
- Hey you. You're the best! - +
should render 1`] = `
- Hey you. You're the best! - +
- Hey you. You're the best! - +
- Hey you. You're the best! - +
- Hey you. You're the best! - +

-
  • @user49:example.com
    Message #49
  • @user48:example.com
    Message #48
  • @user47:example.com
    Message #47
  • @user46:example.com
    Message #46
  • @user45:example.com
    Message #45
  • @user44:example.com
    Message #44
  • @user43:example.com
    Message #43
  • @user42:example.com
    Message #42
  • @user41:example.com
    Message #41
  • @user40:example.com
    Message #40
  • @user39:example.com
    Message #39
  • @user38:example.com
    Message #38
  • @user37:example.com
    Message #37
  • @user36:example.com
    Message #36
  • @user35:example.com
    Message #35
  • @user34:example.com
    Message #34
  • @user33:example.com
    Message #33
  • @user32:example.com
    Message #32
  • @user31:example.com
    Message #31
  • @user30:example.com
    Message #30
  • @user29:example.com
    Message #29
  • @user28:example.com
    Message #28
  • @user27:example.com
    Message #27
  • @user26:example.com
    Message #26
  • @user25:example.com
    Message #25
  • @user24:example.com
    Message #24
  • @user23:example.com
    Message #23
  • @user22:example.com
    Message #22
  • @user21:example.com
    Message #21
  • @user20:example.com
    Message #20
  • @user19:example.com
    Message #19
  • @user18:example.com
    Message #18
  • @user17:example.com
    Message #17
  • @user16:example.com
    Message #16
  • @user15:example.com
    Message #15
  • @user14:example.com
    Message #14
  • @user13:example.com
    Message #13
  • @user12:example.com
    Message #12
  • @user11:example.com
    Message #11
  • @user10:example.com
    Message #10
  • @user9:example.com
    Message #9
  • @user8:example.com
    Message #8
  • @user7:example.com
    Message #7
  • @user6:example.com
    Message #6
  • @user5:example.com
    Message #5
  • @user4:example.com
    Message #4
  • @user3:example.com
    Message #3
  • @user2:example.com
    Message #2
  • @user1:example.com
    Message #1
  • @user0:example.com
    Message #0
  • +
  • @user49:example.com
    Message #49
  • @user48:example.com
    Message #48
  • @user47:example.com
    Message #47
  • @user46:example.com
    Message #46
  • @user45:example.com
    Message #45
  • @user44:example.com
    Message #44
  • @user43:example.com
    Message #43
  • @user42:example.com
    Message #42
  • @user41:example.com
    Message #41
  • @user40:example.com
    Message #40
  • @user39:example.com
    Message #39
  • @user38:example.com
    Message #38
  • @user37:example.com
    Message #37
  • @user36:example.com
    Message #36
  • @user35:example.com
    Message #35
  • @user34:example.com
    Message #34
  • @user33:example.com
    Message #33
  • @user32:example.com
    Message #32
  • @user31:example.com
    Message #31
  • @user30:example.com
    Message #30
  • @user29:example.com
    Message #29
  • @user28:example.com
    Message #28
  • @user27:example.com
    Message #27
  • @user26:example.com
    Message #26
  • @user25:example.com
    Message #25
  • @user24:example.com
    Message #24
  • @user23:example.com
    Message #23
  • @user22:example.com
    Message #22
  • @user21:example.com
    Message #21
  • @user20:example.com
    Message #20
  • @user19:example.com
    Message #19
  • @user18:example.com
    Message #18
  • @user17:example.com
    Message #17
  • @user16:example.com
    Message #16
  • @user15:example.com
    Message #15
  • @user14:example.com
    Message #14
  • @user13:example.com
    Message #13
  • @user12:example.com
    Message #12
  • @user11:example.com
    Message #11
  • @user10:example.com
    Message #10
  • @user9:example.com
    Message #9
  • @user8:example.com
    Message #8
  • @user7:example.com
    Message #7
  • @user6:example.com
    Message #6
  • @user5:example.com
    Message #5
  • @user4:example.com
    Message #4
  • @user3:example.com
    Message #3
  • @user2:example.com
    Message #2
  • @user1:example.com
    Message #1
  • @user0:example.com
    Message #0