From ec13bdc910c5a000e8816390ad751909fbba657d Mon Sep 17 00:00:00 2001 From: Half-Shot Date: Thu, 12 Jun 2025 16:25:23 +0100 Subject: [PATCH] Update tests to be complete --- .../e2e/modules/custom-component.spec.ts | 135 ++++++++++++++---- .../sample-files/custom-component-module.js | 39 ++++- ...om-component-crash-handle-filter-linux.png | Bin 0 -> 5872 bytes ...-component-crash-handle-renderer-linux.png | Bin 0 -> 5730 bytes ...stom-component-tile-fall-through-linux.png | Bin 3803 -> 5930 bytes .../custom-component-tile-linux.png | Bin 4098 -> 6174 bytes .../custom-component-tile-original-linux.png | Bin 2056 -> 4717 bytes src/modules/customComponentApi.tsx | 41 ++++-- 8 files changed, 170 insertions(+), 45 deletions(-) create mode 100644 playwright/snapshots/modules/custom-component.spec.ts/custom-component-crash-handle-filter-linux.png create mode 100644 playwright/snapshots/modules/custom-component.spec.ts/custom-component-crash-handle-renderer-linux.png diff --git a/playwright/e2e/modules/custom-component.spec.ts b/playwright/e2e/modules/custom-component.spec.ts index 7d91816231..8299c0de11 100644 --- a/playwright/e2e/modules/custom-component.spec.ts +++ b/playwright/e2e/modules/custom-component.spec.ts @@ -6,7 +6,8 @@ Please see LICENSE files in the repository root for full details. */ import { test, expect } from "../../element-web-test"; -test.describe("Custom Component Module", () => { + +test.describe("Custom Component API", () => { test.use({ displayName: "Manny", config: { @@ -23,31 +24,111 @@ test.describe("Custom Component Module", () => { await use({ roomId }); }, }); - test("should replace the render method of a textual event", { tag: "@screenshot" }, async ({ page, room, app }) => { - await app.viewRoomById(room.roomId); - await app.client.sendMessage(room.roomId, "Simple message"); - await expect(await page.getByText("Simple message")).toMatchScreenshot("custom-component-tile.png"); + test.describe("basic functionality", () => { + test( + "should replace the render method of a textual event", + { tag: "@screenshot" }, + async ({ page, room, app }) => { + await app.viewRoomById(room.roomId); + await app.client.sendMessage(room.roomId, "Simple message"); + await expect(await page.locator(".mx_EventTile_last")).toMatchScreenshot("custom-component-tile.png", { + // Exclude timestamp and read marker from snapshot + mask: [page.locator(".mx_MessageTimestamp")], + css: ` + .mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker { + display: none !important; + } + `, + }); + }, + ); + test( + "should fall through if one module does not render a component", + { tag: "@screenshot" }, + async ({ page, room, app }) => { + await app.viewRoomById(room.roomId); + await app.client.sendMessage(room.roomId, "Fall through here"); + await expect(await page.locator(".mx_EventTile_last")).toMatchScreenshot( + "custom-component-tile-fall-through.png", + { + // Exclude timestamp and read marker from snapshot + mask: [page.locator(".mx_MessageTimestamp")], + css: ` + .mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker { + display: none !important; + } + `, + }, + ); + }, + ); + test( + "should render the original content of a textual event conditionally", + { tag: "@screenshot" }, + async ({ page, room, app }) => { + await app.viewRoomById(room.roomId); + await app.client.sendMessage(room.roomId, "Do not replace me"); + await expect(await page.locator(".mx_EventTile_last")).toMatchScreenshot( + "custom-component-tile-original.png", + { + // Exclude timestamp and read marker from snapshot + mask: [page.locator(".mx_MessageTimestamp")], + css: ` + .mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker { + display: none !important; + } + `, + }, + ); + }, + ); + test("should disallow editing when the allowEditingEvent hint is set to false", async ({ page, room, app }) => { + await app.viewRoomById(room.roomId); + await app.client.sendMessage(room.roomId, "Do not show edits"); + await page.getByText("Do not show edits").hover(); + await expect( + await page.getByRole("toolbar", { name: "Message Actions" }).getByRole("button", { name: "Edit" }), + ).not.toBeVisible(); + }); + test( + "should render the next registered component if the filter function throws", + { tag: "@screenshot" }, + async ({ page, room, app }) => { + await app.viewRoomById(room.roomId); + await app.client.sendMessage(room.roomId, "Crash the filter!"); + await expect(await page.locator(".mx_EventTile_last")).toMatchScreenshot( + "custom-component-crash-handle-filter.png", + { + // Exclude timestamp and read marker from snapshot + mask: [page.locator(".mx_MessageTimestamp")], + css: ` + .mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker { + display: none !important; + } + `, + }, + ); + }, + ); + test( + "should render original component if the render function throws", + { tag: "@screenshot" }, + async ({ page, room, app }) => { + await app.viewRoomById(room.roomId); + await app.client.sendMessage(room.roomId, "Crash the renderer!"); + await expect(await page.locator(".mx_EventTile_last")).toMatchScreenshot( + "custom-component-crash-handle-renderer.png", + { + // Exclude timestamp and read marker from snapshot + mask: [page.locator(".mx_MessageTimestamp")], + css: ` + .mx_TopUnreadMessagesBar, .mx_MessagePanel_myReadMarker { + display: none !important; + } + `, + }, + ); + }, + ); }); - test( - "should fall through if one module does not render a component", - { tag: "@screenshot" }, - async ({ page, room, app }) => { - await app.viewRoomById(room.roomId); - await app.client.sendMessage(room.roomId, "Fall through here"); - await expect(await page.getByText("Fall through here")).toMatchScreenshot( - "custom-component-tile-fall-through.png", - ); - }, - ); - test( - "should render the original content of a textual event conditionally", - { tag: "@screenshot" }, - async ({ page, room, app }) => { - await app.viewRoomById(room.roomId); - await app.client.sendMessage(room.roomId, "Do not replace me"); - await expect(await page.getByText("Do not replace me")).toMatchScreenshot( - "custom-component-tile-original.png", - ); - }, - ); }); diff --git a/playwright/sample-files/custom-component-module.js b/playwright/sample-files/custom-component-module.js index 0b547a69ab..563b4123c5 100644 --- a/playwright/sample-files/custom-component-module.js +++ b/playwright/sample-files/custom-component-module.js @@ -9,6 +9,38 @@ export default class CustomComponentModule { static moduleApiVersion = "^1.0.0"; constructor(api) { this.api = api; + this.api.customComponents.registerMessageRenderer( + (evt) => evt.getContent().body === "Do not show edits", + (_props, originalComponent) => { + return originalComponent(); + }, + { allowEditingEvent: false }, + ); + this.api.customComponents.registerMessageRenderer( + (evt) => evt.getContent().body === "Fall through here", + (props) => { + const body = props.mxEvent.getContent().body; + return `Fallthrough text for ${body}`; + }, + ); + this.api.customComponents.registerMessageRenderer( + (evt) => { + if (evt.getContent().body === "Crash the filter!") { + throw new Error("Fail test!"); + } + return false; + }, + () => { + return `Should not render!`; + }, + ); + this.api.customComponents.registerMessageRenderer( + (evt) => evt.getContent().body === "Crash the renderer!", + () => { + throw new Error("Fail test!"); + }, + ); + // Order is specific here to avoid this overriding the other renderers this.api.customComponents.registerMessageRenderer("m.room.message", (props, originalComponent) => { const body = props.mxEvent.getContent().body; if (body === "Do not replace me") { @@ -18,13 +50,6 @@ export default class CustomComponentModule { } return `Custom text for ${body}`; }); - this.api.customComponents.registerMessageRenderer(/m\.room\.message/, (props) => { - const body = props.mxEvent.getContent().body; - if (body !== "Fall through here") { - return null; - } - return `Fallthrough text for ${body}`; - }); } async load() {} } diff --git a/playwright/snapshots/modules/custom-component.spec.ts/custom-component-crash-handle-filter-linux.png b/playwright/snapshots/modules/custom-component.spec.ts/custom-component-crash-handle-filter-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..b144ca6a5ecd5a82b5437f939b9bdd40e257f43e GIT binary patch literal 5872 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 literal 0 HcmV?d00001 diff --git a/playwright/snapshots/modules/custom-component.spec.ts/custom-component-tile-fall-through-linux.png b/playwright/snapshots/modules/custom-component.spec.ts/custom-component-tile-fall-through-linux.png index 952b0110b6526bed692a63031cc063ba9fd7165c..0fe98072a04c150c34261f4201449f319db9cc94 100644 GIT binary patch literal 5930 zcmbt&hgVZi&^C&Kf^?M*3L;7o={*RB-lPPO-a|(Ty($WXE&`!<=}kdes7mj>hF%hy zw2%Oyz2WzL?_cnqbI+YQJF`2_ox5jdpACPfp-4u;Kte!3K&Gq&)FvPx6vpdH_ip3g zZ|2m*@!}RlTTzanVu)#rfZ*}EGEi36JN@56kU>0Vk@$e(YT1EDl;bGdVUwdfS5}_Ohw*iIKT3yFXVF`@+ z12h6seeV$Exx=g%y0dgo;0KrRrl$G5^YgR7J?FnD+*Lgoa*lPr0Yy;CziGjFqY!w# z2_V7?bCY*jxA4+{b^?4eJardCj~AajWdBcQ`msn6eZEUWP>HmODY~Bm*F~zI`pT4p z&2!+xRA2{<&Tc1QNN0VhT~T_9V)h2w1Amb^*QMGEr?teLkeB&3jjhd-P8E~ce?(e> zjz|o+QM3Ff?8-OL6ruT;*?)*17wa8`%4VWlm4PH2jqD;|?1<+{HJ-mS+HpXSUdfZ0%e2HhvPZa;wVx7cFljALIpTHG> zMvJC1tqHL7?2`T1Kg99jHlb)>vk$A~P0$B+$nEM%nRkXQM%6~4r1~)d{uhDrJ0A|6 zCUTE+s_@V53mcS^t6orT&{v*-BAx)?dauLY)yV_=n;OV|2+x!VzXD2 zcqAy4y4#R+IJdY{E;`Dq$8()NkhQciE{$8&kZt$kTt-z>C-+b8R+yFPqo& ze8%nCz9;Zx-v>!fhQ(#Q&d8;o( zuBPFwlztLr-5+a6{j&%00s0SjL1E4@!zlZ3-NXL6W|-8XSc?0@sBO zXYJd=#5B?Y8HzyK*3qdHllUc*nMEt6beQVRq5&nL@!dli&wO3>62Q9>S^WOF?aS3+ zeP$5@X)P~Amm?j4gIzoS94C@{Y3SJ4Y-c*|w?k9;L_aDBh9zr#j_f)rE?!q!*eFo# zjxo0T5%-xddOt9N7LTQkCmu7aUXkXPNFQ^Z?f5J=F5aJ+sX+7bQTXOjtRkaJ@*>S# zrFT@ug?!=t3ID2#fzLYAJ)UYk`&}`=on->6aU-9vs3Ns15l}Do|@JBsriX zhoMkrL=c8PF5_*_d>n9^v3DwH^v6rD2e$m=v4TMLkl6@|*z~gxj>^WJ7{H0>{7$}d z{Fb3|r;SU;%*K&c6F~6}e*M?)v&7+&?$fmmhiUQKq`;;)a;xwt56+gN^O{Bx@>f>A z@df$G;6Tw%1Z?wTAxGw}N!WVa(e+_fY3Vz~)-#MBZFg6zH!Cb6+C77MQw1obx4kE` zx1zR-uf=TyRuDwTiDOCYRMYkOd}EgL_0^}TN@BXJ0Y9qBON(bz3u0FoGr5-0k9h%T zJ)RWtAN~6jPjaVa?t7%IjcL-NDL*6uqIx6s$oxF~Ml`k#!ZOJ4pdZ|M-aY(WMkX9Q z{mmkgFLT~HQ`Z`(IysP3Uk=L_BgEJJ z^Y-;qda3~I)O6>55QJ3{9Tb4f6-CW=f1()gOfBl+^O_tr2sgrYp=izBXz=m&XdsxB zU*U*@-E;j{rh*=Fu~Br=yZ_coec06&C;#h*1B0&ARKqd%ml}GykN|fptG872e0ewF z2sU92xG3nnzdY#`qHceIC$QhOBo?x?hBpyB@Lrez1BF}%(Sq&I0=BHCj_e_ND(BQU zg?@R|!sYTkSkaSWH7Z;+c`-1M5Zxop4OqW-8*8!7>HH@Q?c7)~^YIUx&x;gQiF*1Tvu&FdB^9k#_nrPF)*OXhT zR?Qs!ZjR9>>3J?Ps9S<5V_$U5YK5I@!$#~KKE%`}g-;}P3{Wm$TA=Kt4(cMC^#>ZR z-{>j!LmYISQ&9Xt;KZ{`)+@^iVL=qEoha=k{(27JSF@oQ23<*Tt~DN=+mKoX^oiG|U;C5*p|ad>2P{o{OIkM&!Q` zVa(q-y}@sts5iSW6D6)5lawwIRLFwOrStwKo!&dA3->tu)*DEJd4)efx-v;<14fm_ zT!+vmECEs7UwM32#&g-t61gvIhkr}$5+pAPm23HVqqdi4S>!n5Mx>uS*Lm-1sSqKV z!5@ShQ*(~zvT2EQd;?E)^fA;=ekg)?yZ($?ofO)qB}`4Fmxb@Z?jR8a;a<16B4u$7PNX7V=wrwTAq_uswR;EA1;~x=as=is3Xb8OSnh`w7z4i3Yt;$Use)%_Q^Dp$kIIm{zfmxz5<0xcY0!R#n5iefImbqqT%LR_X~-R9wTXMGL#$h2^wP zQ^5kEww$z}3aeB9P^i*?-s8}um+lIzk@|1=YpXo$do9>lMsGJ%TUhvm5*J@sg+nbk z;`n6+XhWe4kLdkMzEU-gP5D&;fo^5!-kk-hnc>pkqb1S#e= z%Um{!!?{WEbRXKl)DjFu8@>7{Yfq*pqC@L!DJ7i}Z^d!u6ZNC)lYqoJAmV0UgMF{X7HGHb5 zZ$Y0UqQ@n`2-RDt-LpCnvsN2?=34liSd2O@tFDdmTbWpSEag%Fl}XT7x_^I+Yd**$ zE4(!URHIVGBb470%qr4QUYf|W?wNdh@o+Z)mDZj zenk-gst`M@91p@(a_~}Qxu+QTAMX#VO7liZJ=v~qJRyEvrZl5HunD>=PU76$QlRal zmd_sdL($?cTimDV$J%Y$ywf5B?NzsH^941`JmiKo62s^8%FuUQ1gLDdghQXu>co-F zsW6Kxc>k8?{5*q@&vw{PexzbNgN?cSKsbfjZ1osaSOcfI-?I93XiIgNG0J+FhNuEz z@VM&vuRd`$zv!~UwEGVXLts1UTxRPVT}VC9R+J^1rGet-EtQp_%Uch)AJ!Qs=4_k0 z6e|=?XIAKDjxcoHYuM`^hFc;-wi66QlSVl3*bMnLk86+Qt2x#nB@*z*aPc}loK)ze z*FR7_O78k(3m8SE%8H3?UC!HCxNLNTW%S}EK8GMO5J!;vc@a9?O2{|n9-iH|wNJZm zZ2#;w3>q+l&x<)c%Yvq+rO8~cZc?PC>R#;)!#URn99-_pwRXpm_$r~!k# zb5%BFmQ<1GzNWTMgfAJnSS=&GwoGI#CFt0XHD-<@7!ik#jd>~?Vlj^A=YQZ{L7(u& z!QyPrQh|kObAv|2OL_Sh?@lC(yW!)_?xa2?;InTPN>PV<#=O;XRI$HLtSz`rah`I^ zry7+{*(t5gxd=Xi=!ANZ$U$2pge>s*kdv6HI~JYEfB8;%R(ydklJGL?!{#Z!>sygJ z7tC^G7qL=+CtuzkFel=o&U*KlmXb;s#=4AKOM1ml>38qJBa(6p&;E-7tx7#R<%jEk zsoMoQ=#PnFcInv!HfwOOM`~pw@@1BdmqyzWw8tQ^)u&V;6SfaytQOz;x!LR^ovLgtFF+MvBDRp}kXI|`Oz9mFa`KSo zF@I4+--GWR!{ab90ibnR+2%>^=m5uS2|zo&1ID<&CuuZ$oL(#xO85DLRH@9uVXcUR zDhSnZE@0PbWdfArLNRrY!OqkLwjXjeziC^%yk#TrB3JOe8WOK;bQQ_C10upEyal#Y|5)wK9Riy=2uT4-h-F%ccdrOoBo*3( zUbt1M2;=7Za*qf1A39d1Ikx@8@)YV%Z#sAs)cSaa^WBeyF}SU+deOqTA99>)Pd(!b ziPM5G`*cJ!8P`WlV2mgd5|bX=KHD#|TM%xeIScFEGS_xeiG%AE;tvYy;+9)`-L>xY zFpjs;dWEIsqBE+~9V(cukB(!Jpc>5FScYS8Qg>m}PPBE=g`JgKqL_q3h0~!!5K_rf zMRte8H*^C+RIaCQRx0Y%Ae9rO`|VA`Q<3~^-5eg?0VQa^fYLNj#aH}m`@ODeqRGqw z_HEw`xEMEoese4;n^ApB7&13df4V^8 zTwdTmj62ncPYdYqRVc$01}E45AWVe&M!R_#+s%~jKXlkH*7eC<_Q=6*Fy_%f9x((s z+sOVs8tEB)&)oRt7Qu23wYnQl%dd80=`SbKPmbosaQB@b%)~=+4^TZ!@pVp~YDZwsY|B_#9 zy=I15#7$A*H>WC4Drsb$myfjM>T$Ebx?9eWAWvJh^REQegQ;}poZBGnWi_8=EJIfE zBLTskdUz9HE5fcA;FB{S1d0p&N?L2pq2#_*`3k0fVgxHbnN5ge;#q%apXRx3y(4l5 z{<hcj5U-*%#FKsw?;P?7V;J#){4=r+y3d(f6#2 zigB0u`j5sQeQ5jf#<4vMNSg0!#<|wA=W)crf(+r^j+co}6V|+>z0}U!Du;i@*h(#g z=zN@vo|f=MlSNF1puk~`%YlvftG9xK11&a^bd)19{W7GJJ(MC%6b#$2Al^Go0j&v% zuT-Vvq> zFijRzJ=rHcCsmCy`S-Wc_uq8$88IW7J`y*usbvtACH*XVuHA2ZOpv1Z7zmWx;tn@j zMKvrJ+@JbVTFIldlo_WJn90sICI0&POMbbzQa;JM1fM=ftyKhhZgMa1(b`Jw@Vk_? zS(IfrG&EGStSq%oaK~hQ@W_0<6oehgkw(OY<8HWKcI7Kkkqn8;JY*q+cAJl!L8?dg z^&CiO)Hxz@0lLx*4gJrp4Q_t<|89lpgSEJCxL|4U;eSkWC;0z6{4Zy`rchA{4tI{K Q{(0l3EUy8qkTVbdAEtwtegFUf literal 3803 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 Ruqyxn002ovPDHLkV1k8JUu6IQ diff --git a/playwright/snapshots/modules/custom-component.spec.ts/custom-component-tile-linux.png b/playwright/snapshots/modules/custom-component.spec.ts/custom-component-tile-linux.png index 410365982b864a0a97d16e2a78a4acf3421ef15a..7c5d6b66e6d2d753dbeee10cceba0445dd1e6782 100644 GIT binary patch literal 6174 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 AG5`Po diff --git a/playwright/snapshots/modules/custom-component.spec.ts/custom-component-tile-original-linux.png b/playwright/snapshots/modules/custom-component.spec.ts/custom-component-tile-original-linux.png index 45c227958337a4e3020726b071e05517771d943f..9a00a3b04baee2147b7447734180bcee6bf5683e 100644 GIT binary patch literal 4717 zcmaJ_XIPU>vyP&ofM7@vkfuRIMS4*{0!Rd;8tGk1q=WPtzygG#NH?@70!r_M7EmC7 zw18BpFTI2odT2S}d%r*Dy3Td}?CkE$&fc^8OnElqxt7XRx*K!=0O0B~RoDvvfJTzq zSG|0m+A54{NK?rkl_X;gJzlDipv=@x#Z< z7teYM^zF81wCW<6fl7W>-Nc-u(vjzA^m)A?Z)a5cU1?_3!l5Q)=IUyjhu4kO#ruqVd-PlD!xXfOp&(VE z0>PFFab$0DVYId&=HtBcDM{;HB^3f-!C^JU-w@rs=}k0z>D z+Y`UZ*Swf89Zw)n-k~M8{#fOha1WuP=yf#gvdtcPSR1W3+zpd>E~a_F0F0FjE|`;k z2oX!RsPYCW2q0v8NcfO9fq6Py4eqfhhdghGJX9Kuip(Stj$HU|L@&9_y87;p`XqY1 zamLqji`H+Mb)%@NXr)=3ZYwwVpXZE68+kk0r)c}a-_T9TspJSPN1?R*TM#jey87}j zA2W8-K)sCtjMu1u{OO~}UAk~b=d{w5<7eW)nsC*y8fH-~0&W`5pV`S8Tv(ArFupf- z#awJkfl&_(&KDXou(;cUQ<#I^{MQKq9dL_B+dHc^FO43% zUggn5;oNQJkKcESoP=g5Rk9d`4y9B#K>L^jYCWa5&#UVO!#x!B)SD4OitlQd52%2? zU`sv|q7#SSCDiQLkp&@JJO1{%jSbx9-&8yzmJXR}-Sda%u=-WAY(4~OF~&jt)dBr< zXb@SVuk&k=u#Ei3H%xNfNw(8qLUmVPzZisZ65=2-JW;3ofgPG~3u48I3zK1%)EzE) zC7`K6X}5O?%=;~;Yi{N-d+?Qxw+5!g{^#(XITZ*X|G`4Je^sJwB3di0pCh6jVTh_b zTAF?W1?pksjlIUUwGId56eoT?+tS%e6hksiH)c21 z-|D|24!p|77x%t;J7UTGw>E$G5G~0>aLf%kL30e5$b~dM!j-%cCed>ozI;*db$F1d zK6l(Ry0kj~OW+$W+$X3>@!evyPu5naMWBv<$|?>2(SbD95=`ADL@&MF*2$}{AqtD) z3_O{$Hbwn7u6sgc#Q=eX!lNzr*zy3+AN26_*hka-VdTn@E~{}20_9NlXV8MPb`!rc zK6hNJMHm)--BB{_De$l{#mhYvG=Ldfjy$vC`Zl^vb$_T;iY@q&nW18fmzxi-STaV& z@YKZ7dK`Jl+Xn57uRlnc@@4ER&k(2aWs9?+1fmX+dmCi7^c|?AnD*Slb*LS$M`=U z^BvO4$=r>Xm%3jsf;fGR4dV?kTZqT|ey^vFFiPYI>{vXZO$h>J6#H_*C6Y)2$BOv~g;v z4-v8w#GoBV@WM#_fRm(b#zsTT{+) zA1`+{XX_lxls-O_F#pa)mAK(DMRwaKs60F|+*7Yfbm1n{(F&NyQ6?K>kOt%biL||` z6~dSa9UU)X*Vk=UZL>OKQ@_gUIMgL3RtE0rg?V{9nCaT&i9G?g{PoS)K-X z#t&^woh8B$N>+o7tO3fBm+5T&=--@w>3`?^qy}yOv(o@*%YDn;>-tO2mz~^kRSzc7 zuJ_OEnzZ|SVZz^Bn!(i@&WmNoj6$$R4{y7;ydpBl^^5Lx86BX!lF*#@{7lA$Z{CO< zQ!ks=q6;LQ;0IKNa$pk!tnkt6zk_sSJBs4^d7t4oFkN%YYGddnZAR}e_vz`90MFtY1%tn15>RdNSsIyqK!p{Y<@IaFx0(iUNr z&}DG@21{&-nWK}7jk>#(P#V|$U6u%o4==J1U|r_e>7y*t)?DB_sH{tcYKrd{{GAkd zoqHyQn48bq%>ed0Yehdy{`~Yh^!!Zz4sTZ>bbo>_O{K}>ow91^W&)+nSoO;`}p zugAcx8pb?2S5Cl{-kAH22ykxF-MIaP3JrOL(Y?qy8YkaKF^{&QUDD&hnNW@jWr!Hj zdqS?ZJ5`@>J?VZtYXO`C)xHwVRJaXzTGT0BD+%|#FDPSW`SE$_@+TROh%~)Iqku16 z8n8RNqcv_k=`&A-49k~`pD8}xRq+5}!MDDi11Pw9&kUeNh1J(qxhVw{Oogqt?ff-h z`0TaKw+92lc<17AosB6QHYV;|4dtZhr|cFiS6EVqa6CVGA#`-$GPwO%41Y)FWA56O z3^zvo76QXH=008gasBwkQOG+Zr;f3pw5uj%mi9W7l9!^OqwwhB3V7#S^q}NxnB_L8 z86QZs%4c1sC$-Wg!1x*lbr)jT(xW;V|2=98$P5%MJBZP5Rjr0WN%?FO(R0z9W-uKc zP)xg*wBm#2MYjl4%PTMCxV?m55BQurzr{b}+nQBAr}PS$kuj@kCZSQ&B=(`_o*h3q zZn2V5OsdaEn8GX^)HGri#JRO!V>y~P*~C%}#g+$UhLom-tH;p7bP1bck&!#EYT8$B zuw{gQk)}g?u4LwAj$?0|aIcD#wET?wgn9&V`v*6sX@*y1Uiehoo^aO*{$VH2Om<7X zgF(hQ$Q;hX%a_^4X{KNU2Ewz4W}x4dQ#v;4fk&dv?zQnwjcWL+v+TDXYl z4tU9_{k-*s38j~6oPS!%XzE9T1clN7cV69S;?E2V3q#VzWC+|l*?9PUBA~jp{Dd5q z7mUTZGj-d(!Wri;Mr1vKqDOmiN2M@MQUObDtP*$o`)GwgVMZut3TlM5hdYH%szqRE zCD1(Pa+1mg73EM@ZKK_4@rt$2rMS+;tLRcYl13j*Gy9t#O87GnVNm4i3X$Vc8WdKs zmU_aibm;?+xQy(>jk43xo%YRN>-)mUGTu5_pHb4yQmX4}T$I(n8|6EFD$zbaVvly?8q5sje|{EhNAea8VmS}A^f zi%@^$q;dKUp_`BfPnXQD3OQ+nN0M4$&jh*et;7crp<6rC@u^9#L#MC6&v(yc#q4qF zIDSMpYiLe7#0jF}w@_?hZM-_UTE)Wo6}8%JEZv6S**xR8&q-f}L=#w6pQVF9SSKQm z1NJOAw#tdP@6cUZFqpd$T*&&g%c-;v587lyu1}Q@9Ck2w_voo7wbs~-eSC)b1`4x0+*BRnRJcd{=LkTleSLPMf!yMFye|8Uc< zbshfDYklp&h8S~O{lKpSZ2@*;0{f^F@gzwWWcs5;M+ju{TJ8f0K@aOW+&=B=P#pso zn`A-N^!@AVuqIM2(SZL_#cUU+{LT5!n0w1734cvcDBg^Qna*sWCaFhn&pY!0bnU~< zY$rc`|LB4pSkoa)F?}R(otD6n~B61?=B9#TD`2yT<1cQ{lIkZ z`z8X`r9j>pWE3^)S3om*d9c95X~f3t5xuKOy|Te*IDu6>xCfo8C^t` zZ`b^1{f?cT-QD7XTK~cq$eD!V{a&=IMj00CYGCxQ`lSK~>uz-UqIwX{6z+$MLGt+g z0$9W*w-DO?=33C^-TLp_ifQn_k1B^&!)ImW&zzT(|MT%>i^6%h&=bjMm`0TXJbS7I KD|+(s?f(EcI1Dxb literal 2056 zcmV+j2>17iP)Px+!bwCyRCt{2-EBx)SsDlMXWGCCBjmDy1PWg1OcJ&=nHE#mHVw{Nafx+zV%@E= zt&Q68ZPBq^Z4@1~O*chd>*`di)S9+V5|rAxb;?dUu|{2<|+^E`)q_;b#^khh*ce+~#Cgb)gwU2nPpgb+e#hr_Hz z2qA>R3$qp>gb)fZ%vyvHLMXg2YY{>Sq43%Te!lm^=*TEV@K1B(M1i&YYo5O8&i)5{ zT;m5ZC$7)$guNhy5ZbnO0RV^ybI{!OX;0r@I@&Iplzyiz(~!|PDfq)(o${ZZ)xKZ) zr4a5y2qA>f8xy=kCNf3rQJp^Ckan)D>CV8=C9SKgvT>Au)9oRI5JKDDmd|S?n$uN< z2Yus1&frzD!1daSPP`wj*ncEByR>!0z4=y_&f7B%8)`o5Z!AsM?N=xc8%yqT-r&iY zx<=Y9*#_-?g*q|4pw2NP0Qfy$T7IdkbP7KV7sM*GrNirv(ShsV>gJlvBZ_xpN`^e( z_qiT4TQUt=l|rpI7S#362x~^xIXWxTbsB}@u%Y0xV@BB2px-xlzrN&Tf;vhO85NUp zxqohPweuIdi%I^ls&!~S*mkIjYXz#?9IY0kc7L??WNEk4J=1T^`c+J1RJ86yQ8(uc zj$Go$Z&qb}a76KLwD$Pfn!C=;JtBk<+L1!M8x_IowJhZq1PZX^?k>-*o}fqb8`_%6 zQuZu#mgd>UJX_52xd;0nN1bjS`f9l8cVw!us+02pfG}n)D7CvIjTKEDSIt@&tIsO8 zyQnOs>2J;koqVtH*7O3`Vw8*4ujcnnk2)o1Zck1P*B+AzWA#~oaJX4x#V0Mb=d{Zs z*8CcWi>{8eH$Mbp(-)INSBx-b&9Cfttxqz3xH7+bh{l(-_4V|%@p( z)!lVy61e4YBX;lIv0sv#8f@YKtkGoAO765?60hHd9fDz+m?|8DwawJ0QlAP(ST)^6Q~xxTfe)b+V`{*UO55EkB6$L z-nea5QeJj~k`XC$^3orE?NFLbi9eSCm@b${$8U0f_nO%i=imrUX>hcqvH$?TPIzzk z*{lb{b6M&`lGpj#5JCuTBcZaE(nTLcNEk5{<~c#4j#aK^0+DOtlyLW3m)FF~H!Q|5 zQYQGnm@ov~OBB3Mr`aMjT zWV}Fu1puNtpkpI~pUU^?G-PCY-V5)n9ZcZaimzk^K+2xFSe2$+Gkv#AC4HU65JCuTFI#1;-#6o^@0^t!&(q08gs8Q0 zpL5#nOAOqyQep0q8Al zWi-Fg1s?0tXWSGoi+UU2p8!BzoYS?W)kFXQ2;XyaUPjN#39P=CMER*PjyZGtR;`W! z0KaFjAHW~T&h@+VduB!_ynB-q_lBco)>Rm8F{B3iFw1D^=9ldcH4{N z&Yw<>TAa9UvkvYy-@8+#5A47_V5=k9$!f93+53s($-d&IgKJh3N#s)Ugl;lL?*i)-UduRiX2ni7RVsB9>}v zMwbXWVaes4M?fqx%sfv{;GUvXWotI0^H z0hvC(_|$J6U;AOx?nDyR0d-1kb9ub%Wffls(U@CqK&7RzsP~TmM5aGe-*yp$79oUw z65iVOzZLJ}8Z&dhN$Tmlu<`w1gb+gL#{hqO03n1B3NOrBgb+d~yte-xGC~L;^y7x- mT7(cnD7-Lh5kd%|@cI`t2}ap;;TM1a0000 boolean); renderer: CustomMessageRenderFunction; - hints: CustomMessageRenderHints, -} + hints: CustomMessageRenderHints; +}; export class CustomComponentsApi implements ICustomComponentsApi { private readonly registeredMessageRenderers: EventRenderer[] = []; - - public registerMessageRenderer(eventTypeOrFilter: string | ((mxEvent: MatrixEvent) => boolean), renderer: CustomMessageRenderFunction, hints: CustomMessageRenderHints = {}): void { + public registerMessageRenderer( + eventTypeOrFilter: string | ((mxEvent: MatrixEvent) => boolean), + renderer: CustomMessageRenderFunction, + hints: CustomMessageRenderHints = {}, + ): void { this.registeredMessageRenderers.push({ eventTypeOrFilter: eventTypeOrFilter, renderer, hints }); } - private selectRenderer(mxEvent: MatrixEvent): EventRenderer|undefined { - return this.registeredMessageRenderers.find((rdr) => typeof rdr.eventTypeOrFilter === "string" ? mxEvent.getType().match(rdr.eventTypeOrFilter) : rdr.eventTypeOrFilter(mxEvent)); + private selectRenderer(mxEvent: MatrixEvent): EventRenderer | undefined { + return this.registeredMessageRenderers.find((rdr) => { + if (typeof rdr.eventTypeOrFilter === "string") { + return rdr.eventTypeOrFilter === mxEvent.getType(); + } else { + try { + return rdr.eventTypeOrFilter(mxEvent); + } catch (ex) { + logger.warn("Message renderer failed to process filter", ex); + return false; // Skip erroring renderers. + } + } + }); } /** @@ -45,7 +61,12 @@ export class CustomComponentsApi implements ICustomComponentsApi { ): React.JSX.Element | null { const renderer = this.selectRenderer(props.mxEvent); if (renderer) { - return renderer.renderer(props, originalComponent); + try { + return renderer.renderer(props, originalComponent); + } catch (ex) { + logger.warn("Message renderer failed to render", ex); + // Fall through to original component. If the module encounters an error we still want to display messages to the user! + } } return originalComponent?.() || null; } @@ -56,9 +77,7 @@ export class CustomComponentsApi implements ICustomComponentsApi { * @param originalComponent Function that will be rendered if no custom renderers are present, or as a child of a custom component. * @returns A component if a custom renderer exists, or originalComponent returns a value. Otherwise null. */ - public getHintsForMessage( - mxEvent: MatrixEvent, - ): CustomMessageRenderHints { + public getHintsForMessage(mxEvent: MatrixEvent): CustomMessageRenderHints { const renderer = this.selectRenderer(mxEvent); if (renderer) { return renderer.hints;