From d16ab09866dae02538903ec63b457ef92ad1fec5 Mon Sep 17 00:00:00 2001 From: Florian Duros <florianduros@element.io> Date: Thu, 29 Aug 2024 16:26:10 +0200 Subject: [PATCH] Display pinned messages on a banner at the top of a room (#12917) * Move pinned message hooks to a dedicated file * Add a banner at the top of a room to display the pinned messages * Put the pinning banner behind labs pinning labs flag * Add redacted event support * Handle UTD in pinning message banner * Add tests for redaction * Make all the banner clickable * Add tests for PinnedMessageBanner.tsx * Add e2e tests for the pinned message banner * Review changes --- playwright/e2e/pinned-messages/index.ts | 34 ++- .../pinned-messages/pinned-messages.spec.ts | 63 +++++ .../pinned-message-banner-1-Msg1-linux.png | Bin 0 -> 1325 bytes .../pinned-message-banner-2-Msg1-linux.png | Bin 0 -> 4174 bytes .../pinned-message-banner-2-Msg2-linux.png | Bin 0 -> 4290 bytes .../pinned-message-banner-2-linux.png | Bin 0 -> 13394 bytes .../pinned-message-banner-4-Msg1-linux.png | Bin 0 -> 4142 bytes .../pinned-message-banner-4-Msg2-linux.png | Bin 0 -> 4410 bytes .../pinned-message-banner-4-Msg3-linux.png | Bin 0 -> 4449 bytes .../pinned-message-banner-4-Msg4-linux.png | Bin 0 -> 4142 bytes .../pinned-messages-list-messages-2-linux.png | Bin 13654 -> 0 bytes .../pinned-messages-list-messages-3-linux.png | Bin 16907 -> 0 bytes .../pinned-messages-list-pin-3-linux.png | Bin 0 -> 16914 bytes .../pinned-messages-list-unpin-2-linux.png | Bin 0 -> 13658 bytes res/css/_components.pcss | 1 + res/css/views/rooms/_PinnedMessageBanner.pcss | 119 +++++++++ src/components/structures/RoomView.tsx | 10 + .../views/context_menus/RoomContextMenu.tsx | 2 +- .../right_panel/LegacyRoomHeaderButtons.tsx | 2 +- .../views/right_panel/PinnedMessagesCard.tsx | 166 +----------- .../views/right_panel/RoomSummaryCard.tsx | 2 +- .../views/rooms/PinnedMessageBanner.tsx | 252 ++++++++++++++++++ src/hooks/usePinnedEvents.ts | 212 +++++++++++++++ src/i18n/strings/en_EN.json | 7 + src/utils/PinningUtils.ts | 14 +- .../right_panel/PinnedMessagesCard-test.tsx | 7 +- .../views/rooms/PinnedMessageBanner-test.tsx | 235 ++++++++++++++++ .../PinnedMessageBanner-test.tsx.snap | 166 ++++++++++++ test/utils/PinningUtils-test.ts | 18 +- 29 files changed, 1130 insertions(+), 180 deletions(-) create mode 100644 playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-1-Msg1-linux.png create mode 100644 playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-2-Msg1-linux.png create mode 100644 playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-2-Msg2-linux.png create mode 100644 playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-2-linux.png create mode 100644 playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-4-Msg1-linux.png create mode 100644 playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-4-Msg2-linux.png create mode 100644 playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-4-Msg3-linux.png create mode 100644 playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-4-Msg4-linux.png delete mode 100644 playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-messages-2-linux.png delete mode 100644 playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-messages-3-linux.png create mode 100644 playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-pin-3-linux.png create mode 100644 playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-unpin-2-linux.png create mode 100644 res/css/views/rooms/_PinnedMessageBanner.pcss create mode 100644 src/components/views/rooms/PinnedMessageBanner.tsx create mode 100644 src/hooks/usePinnedEvents.ts create mode 100644 test/components/views/rooms/PinnedMessageBanner-test.tsx create mode 100644 test/components/views/rooms/__snapshots__/PinnedMessageBanner-test.tsx.snap diff --git a/playwright/e2e/pinned-messages/index.ts b/playwright/e2e/pinned-messages/index.ts index 5e61b11e85..bb7705ba98 100644 --- a/playwright/e2e/pinned-messages/index.ts +++ b/playwright/e2e/pinned-messages/index.ts @@ -168,9 +168,8 @@ export class Helpers { /** * Return the right panel - * @private */ - private getRightPanel() { + public getRightPanel() { return this.page.locator("#mx_RightPanel"); } @@ -183,7 +182,6 @@ export class Helpers { await expect(rightPanel.getByRole("heading", { name: "Pinned messages" })).toHaveText( `${messages.length} Pinned messages`, ); - await expect(rightPanel).toMatchScreenshot(`pinned-messages-list-messages-${messages.length}.png`); const list = rightPanel.getByRole("list"); await expect(list.getByRole("listitem")).toHaveCount(messages.length); @@ -243,6 +241,36 @@ export class Helpers { await item.getByRole("button").click(); await this.page.getByRole("menu", { name: "Open menu" }).getByRole("menuitem", { name: "Unpin" }).click(); } + + /** + * Return the banner + * @private + */ + public getBanner() { + return this.page.getByTestId("pinned-message-banner"); + } + + /** + * Assert that the banner contains the given message + * @param msg + */ + async assertMessageInBanner(msg: string) { + await expect(this.getBanner().getByText(msg)).toBeVisible(); + } + + /** + * Return the view all button + */ + public getViewAllButton() { + return this.page.getByRole("button", { name: "View all" }); + } + + /** + * Return the close list button + */ + public getCloseListButton() { + return this.page.getByRole("button", { name: "Close list" }); + } } export { expect }; diff --git a/playwright/e2e/pinned-messages/pinned-messages.spec.ts b/playwright/e2e/pinned-messages/pinned-messages.spec.ts index 53f657ea7f..339c3b1f0e 100644 --- a/playwright/e2e/pinned-messages/pinned-messages.spec.ts +++ b/playwright/e2e/pinned-messages/pinned-messages.spec.ts @@ -48,6 +48,7 @@ test.describe("Pinned messages", () => { await util.openRoomInfo(); await util.openPinnedMessagesList(); await util.assertPinnedMessagesList(["Msg1", "Msg2", "Msg4"]); + await expect(util.getRightPanel()).toMatchScreenshot(`pinned-messages-list-pin-3.png`); }); test("should unpin one message", async ({ page, app, room1, util }) => { @@ -59,6 +60,7 @@ test.describe("Pinned messages", () => { await util.openPinnedMessagesList(); await util.unpinMessageFromMessageList("Msg2"); await util.assertPinnedMessagesList(["Msg1", "Msg4"]); + await expect(util.getRightPanel()).toMatchScreenshot(`pinned-messages-list-unpin-2.png`); await util.backPinnedMessagesList(); await util.assertPinnedCountInRoomInfo(2); }); @@ -87,4 +89,65 @@ test.describe("Pinned messages", () => { await util.pinMessagesFromQuickActions(["Msg1"], true); await util.assertPinnedCountInRoomInfo(0); }); + + test("should display one message in the banner", async ({ page, app, room1, util }) => { + await util.goTo(room1); + await util.receiveMessages(room1, ["Msg1"]); + await util.pinMessages(["Msg1"]); + await util.assertMessageInBanner("Msg1"); + await expect(util.getBanner()).toMatchScreenshot("pinned-message-banner-1-Msg1.png"); + }); + + test("should display 2 messages in the banner", async ({ page, app, room1, util }) => { + await util.goTo(room1); + await util.receiveMessages(room1, ["Msg1", "Msg2"]); + await util.pinMessages(["Msg1", "Msg2"]); + + await util.assertMessageInBanner("Msg1"); + await expect(util.getBanner()).toMatchScreenshot("pinned-message-banner-2-Msg1.png"); + + await util.getBanner().click(); + await util.assertMessageInBanner("Msg2"); + await expect(util.getBanner()).toMatchScreenshot("pinned-message-banner-2-Msg2.png"); + + await util.getBanner().click(); + await util.assertMessageInBanner("Msg1"); + await expect(util.getBanner()).toMatchScreenshot("pinned-message-banner-2-Msg1.png"); + }); + + test("should display 4 messages in the banner", async ({ page, app, room1, util }) => { + await util.goTo(room1); + await util.receiveMessages(room1, ["Msg1", "Msg2", "Msg3", "Msg4"]); + await util.pinMessages(["Msg1", "Msg2", "Msg3", "Msg4"]); + + for (const msg of ["Msg1", "Msg4", "Msg3", "Msg2"]) { + await util.assertMessageInBanner(msg); + await expect(util.getBanner()).toMatchScreenshot(`pinned-message-banner-4-${msg}.png`); + await util.getBanner().click(); + } + }); + + test("should open the pinned messages list from the banner", async ({ page, app, room1, util }) => { + await util.goTo(room1); + await util.receiveMessages(room1, ["Msg1", "Msg2"]); + await util.pinMessages(["Msg1", "Msg2"]); + + await util.getViewAllButton().click(); + await util.assertPinnedMessagesList(["Msg1", "Msg2"]); + await expect(util.getRightPanel()).toMatchScreenshot("pinned-message-banner-2.png"); + + await expect(util.getCloseListButton()).toBeVisible(); + }); + + test("banner should listen to pinned message list", async ({ page, app, room1, util }) => { + await util.goTo(room1); + await util.receiveMessages(room1, ["Msg1", "Msg2"]); + await util.pinMessages(["Msg1", "Msg2"]); + + await expect(util.getViewAllButton()).toBeVisible(); + + await util.openRoomInfo(); + await util.openPinnedMessagesList(); + await expect(util.getCloseListButton()).toBeVisible(); + }); }); diff --git a/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-1-Msg1-linux.png b/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-1-Msg1-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..d6892c5bbff22d3ae7c10bd62f3de57ebbc44189 GIT binary patch literal 1325 zcmeAS@N?(olHy`uVBq!ia0y~yV2)*AU~u4IVqjp%+u3!2fq{XsILO_JVcj{ImkbOn z&pllnLn`LHz3ZJJQZ94g<NtST*$Jkhi;~22*!H@*?ESIeDEkekwYiVD16?*Gx%6zA z<*j*DuIfX;SD`68g1F{waWdT~l+C)<oWCj0;lj3$g3env77Cgq+>k5dIJmv=@*cbS z!Qad$SKiro=G>WMMLS~{7!q!DfB(+Nz+j;8!ij;QNsom=VG%bY1II1_hK3Fh4<xJv z;w|82Wat3#$W_!L(8aZTr@H^VKOe83oxa9k>7TtWN`W`#GBJGk#&xIl?RV=}eE)v@ zD12T#y-()nx$9e_kN0cqzVTyZsHol;qZfWd_h0Sz`Fl%W{{CNPV=8a`?5_T{8oR_j z8Y~PF9bEPG4_iJiov-`z!_CU4>hhgV3=NE{{pVSGs?6Jb^EqGqlV4w7Z;Z(K|L?E= z+3Rbgr~9Z?7kW(Bi=Abh?)UzmI75Pk#D(+9*RNjv`lsUky}ioreP5EStG~aC-Ify> z8XEeLkC!1~h2)Odh?tl;XVcElwZ3lax%~3xw6m}N-MDeXBKOvoNs}g3ets6ayG+;q zOxotv;p_D@H8u71?W?|I{9}6f<>lqsvuA5-YyW<1!@$7SZujz#w0ZP=*==`r{B@J= zJpOpLdH%b7DL1ZOEq!pHan`I^e~$O{^@(bS$=FnESiE@grcFk3{hmL+diCnfoNZgT zem&I6{rlV7)BNIkF%dB_f6AV-Fc=&W{b6gW*wPl9?l<4||C>KwZhl_ut}3qo>%mv^ zt%Z+|ot&(Ge`oRXHEZ4+=@d>)O}%@aySuAPsPo9$=<R9e=Il&9-uLIj#l`N&`(#h2 z7@bTpn(1@x+O>7DySF(kX9XKy_0ZpbevU=yvsUl^|3!bEyu5xtDl_xtr>Cc1zkdDs zyHwuIO-ri-jb`TL<oGPVyfP%~<)x)(&z}7$EwFpnu4O(mC&e%S&CkFPw{k-4jW4%< zUQVyC|7oQ@``o`@t4ga@tz5Zs{rdeyPrcM8NA4_2J@5MY`T6{;tgP(p=q(u+SB0*2 z;z&N;clK#fZf@>R(Y*V0oAcK(GPG@WDoZ@w8@+z>t@-A0-<&J`XBsBERaRDphF)#s zm3HfqxM+Jm#VB~WUv6fmr;5<Vh%aUDQjB({oSby))~$Aa`Fne-%fG+7yVr`Jq2b|* z3E#!*etmrO^ZogkmOmeUm>8k6t?q2syu*_&F20wsIeL3u?B+Dz($doNiLS0ke|>%Z z{M_8zH*ZD;1{VJK@bJ%{3k#iRo8`{3D10=-FuCmQt<sN=j&8S5WN1iS@?n4T^~>h> zYvsF-?)&@d^uF6iHy7=U(GlZTjM-OHd9aD~?c2BipWkC-U|V^}zW>htZTa`*`j3~t zyCdmzV{`iXH#ax`{@npeJB`2NUf;X9E%)}-)#1S_L$sz=eR$yby_%Pip<?I4vb_bD zmU!~=^8T$AVPI(XzhCySrEuxT9|5~nI2jC7zP>G1pF4MMr^})h87pF^vM@+g{o2OO z$RMFpbCR3E;X*3|gG-4b1B0VD6NA9TRt5%^SPljU7Z495EC}L}p-6Mr&1?7WA7@~2 c`2U+f=YsZ&9)Y?n1_lNOPgg&ebxsLQ0KcAfXaE2J literal 0 HcmV?d00001 diff --git a/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-2-Msg1-linux.png b/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-2-Msg1-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..153ad2d07f0b9febf69e9c46a38004a2b7cd7516 GIT binary patch literal 4174 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 OVDNPHb6Mw<&;$Tg%m}am literal 0 HcmV?d00001 diff --git a/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-2-Msg2-linux.png b/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-2-Msg2-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..98396be1f829c1fbc0cca1ee16595c6979919759 GIT binary patch literal 4290 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	Xl+vt!H;k3J%(7`M=`Bfm5e~qP<t& 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 baqmB~cIIs_^LY|cAZK~H`njxgN@xNAVFeji literal 0 HcmV?d00001 diff --git a/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-2-linux.png b/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-2-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..f583649aaa95f77fb5d5072f6b83e36f771a78b6 GIT binary patch literal 13394 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 DrR|39 literal 0 HcmV?d00001 diff --git a/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-4-Msg1-linux.png b/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-4-Msg1-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..8169ca9cfd14b9ae5ab628bc8fd8c2c281e3086e GIT binary patch literal 4142 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 literal 0 HcmV?d00001 diff --git a/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-4-Msg2-linux.png b/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-4-Msg2-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..7b6c9948212df8b8cdcd71027b06ae0b4debdcd4 GIT binary patch literal 4410 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 literal 0 HcmV?d00001 diff --git a/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-4-Msg3-linux.png b/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-4-Msg3-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..dfec23cb59097a8272ed2f0b0bb50bada67f921c GIT binary patch literal 4449 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 literal 0 HcmV?d00001 diff --git a/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-4-Msg4-linux.png b/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-message-banner-4-Msg4-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..72abbbb2606cd0b0b5670ae7e146ff8e7d436bd9 GIT binary patch literal 4142 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 literal 0 HcmV?d00001 diff --git a/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-messages-2-linux.png b/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-messages-2-linux.png deleted file mode 100644 index 82666b0d95ff5d0728af128f5f1e66757199a8df..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13654 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�ZZjuu`7+txpHn3D{g;NY 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 MboFyt=akR{096^!=>Px# diff --git a/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-messages-3-linux.png b/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-messages-3-linux.png deleted file mode 100644 index 98e804d897d1de7194d1c924ef1f3170f44e81f2..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 16907 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	*_PRInY?r6hJhlB346mmynfznr+3xB* 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 diff --git a/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-pin-3-linux.png b/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-pin-3-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..b3176cc698a0d319735348abd2845df74a28b680 GIT binary patch literal 16914 zcmeAS@N?(olHy`uVBq!ia0y~yV2op6V7kD;#K6E1F5O?jz`(#*9OUlAu<o49O9lo7 z22U5qkcv5P@1{EhUq5{O<75_&M6DBUDgM!cjH%Xz`GN(v!?ItmSR59eJ9q1~$lR^} zu0~nwtk|)-ql25p@yNk|DY~H(d)F{{&J%yw8OYC=*QD{!ZvBIE%vJmERBw*3?B_n) zQ^Lv6AW|01&%kic&4ZaCK!KORq0xkaf%Ostg9sS{UR`%%_Buqw$H(gnbhRig^l;%w z+#I1}=G}QXEGQ`G(E=BSqRQm<8HX+fM2E*8UN79~vff9$%f&@Oh@<7tttzqZrKdu} z0>cXW8Sb&?{}2d1p!Vt&tLdMpg&(d8?)Os>3cY^iQ}*kSom!{7WPX<Oez41!?Cf*z za{sO>$57M#md(=yxLiZ8{`pnaIA=Foh5VMQifZ9fN1D^N<)xbL=PPBHu#%VG@L8q+ zS8ETuZdmA9agNqcIgATrvu`{1R7z<*mEJOAj=iOW^|fv75{GY3*joBkch`^1o&b$i zYggxA<h`nW@w$F&Z*5q_ilr-GzI|wxk|1w3TWCk*=jopNo_!3-)j4~-UoI_UfjdX! z@5g2O<=6Mw$$jeI@45Mz{^vJujdCCTFyEk`;eYFcfN=7RHmSN?<LNrOy8qv2?wh=~ zx5wAC{!aQK{dqRU_fFp}eX^lZa;ByF`8n&?ua`GH)4yxO;=N}Z_QfeJT(Mz=h0dc- z$KLL~UbET5*}3-Fm(E+aW}UsG>@YjyjexhW_xbv;7q4G_I~DJ;FreaT)SitC_s#8n z`g(SibLNV*tLxux4Ba*9(kAEQ=Rf_dk@hYY6-|9*q$HSGcU4K>{r1fWUtTG9j+YnL zX6M~|tbP5Fl(+M7zFV=fZ;r%EOH1bctn`mL^!8t^&C%z44Eef}?Kd_zE!wU5{q%f$ zdBYw1m+*c4+Ejm7xmeCttgB`H@`bMLGgu~@T;ZNon*6xZ_36dn=Ra!xEvUQKTk7be zARrX^IsV3%zg%YBsz1X*r)uZiixuPke6D4}pC+f5lmA41p3eK?@zI9`>tgpS3UJB3 z%~A7{Si5qeUfi;cku4LxoOv@j{apI<CxsR=?$xsmmDygGUJ^XNYhuOooF7a7G%>}_ z?VHSe%*<?F<mc&M-#^wA>P&hp%&8dnZk;pRH(pNLQgzGF$jF<A*FN77=p6C?|75dm zyDwe(q^y2^$-U|m>(^erep%LT$A0hc{40fz-riZI`z|OX=ig?h(9n17e%~0A-9J>U zdKAgI{oOxlv6=A!896KLb07WSy<PUT=%wCHzO0K3v%d0k8lAK_QezY2?d83>_`h|f zS<;mYjX7q~3IcO1q(9z&ygY50TkYPe;Oklc6x9wsF-s}#J9cW-s|&%2Q$w#Z|Ejok zJL+WIj-Td%mN{nKM};_Ar-p_Wa&Dg#^zOIWr`;8<j){VbF5bb9r@q|yu~T&F)XB`p ze^q?hRcWpH<HSj|^wgB6IX5@DPdz<X#Nb%{nGJi6`<vz7kBtm<<=8oS%C7GY8+Prw z<sQsbv$yK~|JM_G6l44Ms|s~4W9{9(byLR<iLH5$`S$u*8LRnkFfq5T|CsgX>}}t7 zdDr*ZPY%B9#v^G^Ts2|dx^wrK58kw_ywce+p*uY3pIynFJ7-FsZCSuryC>;U-n-w% zE_=G4T-jo~|Nr7;=YCgYIplAb`~Ul|eB+h+v(xw%%=|w^p}EJo=WJTPl+}eZS2WDu zpFFu)aBFGl@$)7njxk)XqIl$%Clp<~@Z|2qSyFW`PHy=0sf)4JCiPD0go?jA=WlX7 zenj4;rb*z@t<AR$_Sg0H2cLL;y~|}$)1pW9eDfa^Sm@ct{hhsR{d(<xw{I+tzCOpj za%Cp}>^Y^ca$M4bANwz3?c8r_ZXCP!;qo2Q+kgM8nzOsWHQ2fKU%GL~l&PGGvRk%( z`}5B~`LMB}8IP2`SB-zlzi@5eUf!eOZhYIW#p}dQo%wggbno(;yQ_b#IdJLDn)&P5 z6`wG>|Gu;5e^1YsmBO5gdt-OcE;ZY>%|yMWMBR_Gv;6(v|NbTK4yE#zZe^Wct7EtG z^0iBMzPop%%+Zx~=>DhK==DueZQbFQ8&14&|Nr;f_lZ$;YhA@JKWzSGdX1H>UE;8b z$<Eo*+b4OQKDAco%&g0;&$c`hJtuD^DfvoVL~Q=<g37OL^QY<kdGqx$<Hz~6A75H2 zx&#L&Kl`HK{5Sl)k%Y9A$G&S<Usn8gbep`{Xmjz;KesBq_f5Wc?s7V7%LMoTw%fLE z6)ShFIdl4lrpk4NRjXn?avZ(i<^L%=JA3w>y8-+69rv3Xy|HZa+^ti$POaR|FSA2S z>q=*ffT`)c01c~BvqcLwyohuRy!Tjr(%Ppszs_H~6;yQb`I7|gz3Zp(IUMWfIeX=a z;<2>N?Z3X>{r-GmRNdOHO`j$(emVY9MZ)IBMXmKEMQ{H(rj_Nng}u8w<+r@mP3@ZB zx1wg<ikh|U+O%t7&+f0gTVttJ_T)n2di`$;C;xrGSj*A9V&zAkFJCQ;>dSSL(vvN- zUU+}E+q%VsQ&H!T(xv|^xGLUwUVF#J|KjrHpUqFMut!?<JNeJEt$B0b^>bQ~dYPG_ zRmqo<CsVWU?y|ZO6}{`*3o+^W6`#w34jZ&8d7k4?%(=FD{|YhQ1)Do3Ce`I+%n8u2 zss0y~8#|XPeCf1!>9U8L-fU)Ln~~G4TB<z3D|D)L-4y{}-ml()*Mr~LPuXjr*m5>6 zsaa@t`5R8Y+CpoG8t+Z}_RZV1VcD{_ty6byUAlAQ!bYau33+M1)+{)2=FE{>r|#T3 zb?1P?`V~uDYBEaAOwXM;w|3PkG5wh}`fI<I9bdoJ*K4P~0LSlNJL*kR50!iGU$JIY zS663!ZBou1U#AmOvkULqm&`KGzICAPo_txUM)kj#P29@Pf7>M^OG|n8AFJlSB+2iv zM}NZPH_kp9BJ*sdC;ok5Zydb1U;X!N3F)+_Pv+W4D}Ls4E#^1mR7>a0G4oc)c*MVG zmsI|r69?P<=j<)`Db;><TCMt~lh-^Xq$Oi^Nok98$-K>(7armg)AOh()TVm(wv->A zqzqFIOq>5b?|16__2Kzq-7Ya*b$_0`>{9(~U2;Ln=D_#qw)KBDJ@2pEC$}{9>BQ;l zHBbI!x_qo``Lc7r|2_~5)hoZTpf1biUhfg>7J<#@j;;59la%JfVR+&Fly3%~Uv0IJ z^Z)wo?iKgSe%0L)H_lhzmshkdd;k4gL3LbUrKQ%ij|@kCGg+RrIKskoaODQ>ot6G7 z-(`>UNLT#vY5B1(CAnN_c74ZQ3FhWP^UwMlrcHZxV`6j2&O0Bv12@I99LxOn+n=RR z+OX`&ge~oo)qH=7-(0bDX5PD$+ur!X`zvRziXOUltLWmLnKFFOA1r*#&OiUb%2j&v z%unAq(ID_CF}yv}SS>6x{QtM-3t!BTp6|o`WK}_QX1Ug>Q{B(cniyTNFZy%lp8dbd zPhW0MS+Fr~Z*2U0jeT=1%deSy)?23N?$0i7xpMX8h1;|FPwL&Nvhts8v2V+oKi~KB zxgR}JZ=*T^?mNBs?$c+hlk(D(Rx-37mb5KNNDqE|XODXLx}%rPZ+zNbk@(a`&&2pr z?nSGwOpd9c#q(#xMuhxP+5dpq-CFW=#)_3j5>^@kKR<JwTzlu!bJ2Lcc=HYOxBq{U zm}|T4`;;DMov(Gj>iy?^`~J1!=^F<H0hhSWmpNHa60-mPisIojR1+8RlHqGVoA*q4 z>D-c1tCz1%L^PaDTg;uSt)=#F{e)z@d3)dFu6_0TwSH`G>c)tQPeIa?3Og)sMO)tr z=Bwjte|-J?>|Lg5?GlqWvsuQw{o^u~6Mz5X$~G6Ji$}E$0}Vg2y1M3w?e3m=GGKq* zCi%+NYuBEE%0mGsEv@V)_1js^X0KhjPV2cF!>y&;Y>&*CfAVt$S4C0xE+sRj3wm4M zDju`pl`)I%RlokW+*B@nqyHs_4F6l-1SY>e5fb)jg|X}|t2{#nlcl`;hL!&_v^5J& zu7pN^iP1Kjy>#U|t^dW14ENY`OFJ|ln2N}lMF-Ele&cz%$6@y?3<ej}+GiZ<3ldFL z6-`}w%)YdH@tPwCKZ`R+R3C1i(e%GTyYPmWjLi#%3sLuOD7M)@rmWEoYNu-mIu*?q z+4|Lh;lbNQE*y#91Wg$(^gV21V$hht#<0LailKoilYxP22_q>2PM!~=*F5JA(p!4p zX67%IwF?%lShZ+J*M^R^zFBSSW=&i>?{tRx^15p>sVbZg)*d@m8M9)=_M(+qYdLR= zm45AKsY{*Pb2P+s=e^)6p2!z#uQ`S){$^!p4fc_GmCZW+`_cJ#r9wl)E}sd#vL&=# z@7v4I8&^-_azD41x#5te0<Y=$pZoo6r-;oxn{YR;`EA-8skN(4PEBWESWxgO?(_5I z;(rYa<TvXHIK7+W{rh14{mbpGMSRQ*BHrsvLPSE}&Jme2U-7zh(DUWuZ)XX8+OxrH zUN1vKlHvXZ0#`V<_t;FBIbr#P!ib%vaV1H!=Jdz39J9MoX!bELk5Tc7v+>@a&ec8T z+o$g3I$hsw6~6M(d;KRj^NY9Ll(J^Zusy?nv?JEA>lKrtit@j}BkLq8w{3WGUi)9P zf4caT`aAEN`+wI?hz)qR|Ld3V`q-&)Zpoj@ru`S&$<BS@pP|p;&xclR$i3Jldur$W zMf1f&jH18)nfvDKa^X2XrIWY&-8Wi$ep+Vjr0ss?CRgv4ygK&Nn&*A9$>acytgCPL z=l*W}&T@FU&D>uPh4ya>JH`}KDmwqA-n!&DUvx@16whz!%9ru(oAh%^`>d{8!P0vE zw~TrYR+P2gS8G|r{pnIru%Q3Npx{XH7nWt8SH>TH|D)7ceEy~G^v?YPvXOrt9p5=| z<A(!F|7`M-KYs3a+Hc9%86C^jQ*8de3-HOg_1LO$L3``LPlbEgEzNUIxwt1k{4g)O z?}(nvz2d7Z{bIe}3JZ^JY7Tt<K4p5ywHYrmd_ETbI(L8W;k1+YR{r_TnqjAw&U^Lg zpBWFLjl?c&zw}eB=-G}?<}<q_KW^D!qnkH9&+TzI{~xQQW%FF!CAE*W-C3vi+*l&$ z&*9}Q0{QI1FFWt?Eo+(Z<BR&E{OfF0t28zqjbFq2Ws1(R^}=hcWFEiI%TB&x_$KVy zp1<NpFXu0@{~9G&q^(_F6~Fvu-MPr~r`p!pOV#auD6?e4o~q|Nqv!J%ecMu<x%{kQ z+U1k`*DbS}@k&qbVbTr9THlN}-`&@nr!OyhCw@=#s_CC2yH}e2X-ihL)iyU)@3&h0 z)xa{_qx+oD6;A2dtIq`gdehIqtQ|WsKxCV)mYzwcz@^jw4=Zx-<;}G^YbWrb`To7C zeGR+vYS$|0TAi+3QS03v5)!!fNZQM+PfOIxE<MuR7}<J$_0jw5B(7H<{<z~-)x)mB zz45nJ29%_H<j_9M$KCebWY*5#K}C6oKPg`PQ+4p*&%<ZFY~fIBo_m&k9dB&Cj^7{i zIq~`&(RSy~MJ!+HtlDztw06?w6P@ebGFKP=EN!~*nqS7JWY*?j%kSLpyYBPLY3t~9 zdhhsr)7???`{n+5cK#fa_C*sG&z<^ZO_(h6WRoQ>X(wj97JQMDvfQ1+a_`4eH+6Z- z8U6njc&Z5SML)`ZwBo+?g6J>vJB`fFDe&%++M~X7s_XgHOJ4^>#Kr21NM^4-85i#B zdh*l;X2l~Lns-@+uUxWe;qi@`{hW$_uggq~voKxnu}SRl<KlxG=4JQCZJ)FG{OyBB z&fdz%;O9;+{`>4r$hp6Vb~~vE2|96fe|_}2?S0&=tE*-#c^LR9Sh6_Q&AL<m)}9^e zepSC(?_O`$`I4r+@$Rv*sT0|5O6T{i-uiH5OV8?+mC02%J=EOpo>p$z5g~ahF8rAO zOjnN+haTpvRGnh+M(z5gkkEBcu3x=!ZS^XXKULk@SsaSDvUvS}#R$K!T(|x0%p+%x zocW`>TzDG0`}!~C)9+YJ*m&9eQ#{kHdp(}X?`=;MY}l&QQc}7hF!ZUA(;D3~aWk*3 znsFyvqdrVAdELILdWugX(*n<ap03xv>h#a^o4QoF4Q^K?r~NKfZmE$jTDxb}!)Gr( zzq*z0yiU-`?(=K4$eyD~f=;hkd*gULi#Hnz2`*ZDO!j@A^}V~-P9IeH969q#;4O)A z>*R$Uf9f<NjZ*!O#5#2>-^;1EWKGw8eIrdn?f<hk?seKPGjmI-l;V?m!SW|}G`FZ{ z*<77>cg~dx-u3odwiyVQKl~cGw*6#e^P9!tdzJeIoNE6pTDEAKz@ml9uX*N2O0|`2 zk1$ws+&^7tx1N>3!NYw5MJi^x+dup~lxWLdzI}pDTK<~J6K3A8|0?KT{rIc!-qieJ z--hQ`uk10L?dSKg@Xd;Iwjz_K#Rlxlt(vdK{`qmr{25y&SpHU0e)sIg>=$>=YFbR5 zaW!!6ZoLcL0*e-|+Vrp@#;q>$##)`~<hkCO{VL@?Pj6~ABx(NpE2ZVVYAdhFmM^Ap z^Oxo>P^_!kdZ^rs<EGi(^|QBLJXgH^TigzBj-LnCTyFEUbBxo!yUoI&{KTKX6F<K6 zpIpQp)>9n*_|&hDwr_gYui=cSwfI)x6P3I7z`2O$*7e^dYj>Mj3Z)nSoo(+IDJ&&D zbIRxUXMJpS@Ad5S)BbC_>qVxZlSNM0lT)0hn-?ojF7i9FT)O;9gvp-gvl#p>%efXr z_{`Jz>-+uf(aO}`v#}*ftJW^x8K4mLXv5A;OQMWoW81fDe)TqMpDH$YZ|<4-y=&Jc zuiE=hY@RRAg<~^fjs%_OP!Z}|F5q-SChY%BeOtE|=Es}QCJH(|>Q^(oXTh*X(&y5J zovYVW|J&I9&Sqb{1Bc|M1KCHy_pycTVhh`)Jnh@Z*{>ZrPI{m0w=SCg@fhQSvk66x zg}>kYy?dGObcDnGp!9S0j%@2~g+4xUe0a|DVCzj)qib`;jV`X-U)p_)nSty06SF0A zr?*bxTE1`EzaBTI6PwRG`ug|#uX6>3l5dyfuT-8_^f=<vRA$btp_}fRO<H_r+vjZ) zHZm~mk>t6*{^5g1#)0+sLVjfIS^h2M+b1oC0G+n;OC>)}T`v@VF#r3iBTsu`+SorZ z-s9rAydZVKL*uiq8=YU;uin0F-mawWoD63S>e=3%NUime`6_D4*F8_|@bn*AS=kH< z>d!I*u0A=(JMYFpkKlifFCt6k6dQQVT>fKu8WV$Y(cZk}i#J}o^PqE;l-8#lm)Lf5 z{gg><dBXa0*&56}?@j+Q(@L_Y{xi3CcyQY4+rJ~$bk5bTYY=9*C)f2e!FpnV$mjEK zg<tEN{jZHTwO-l#YuEhePu}U6-D_lcuy*l@{=;imuHd~bRa#kJGg-d<we{W96H57( z>s=TYeAO`GP5N5n`08m-i?F7@oJfdBXsAfIpy0&|ftN3Y8gIJ%+Va%K?0RWS`z|(y zsM(J$Gcde$u>Sda?u?4lSI)dz{?>lKUAEH!m0)A-pZDiPs|fMRSp_N1W~%tTb+So^ ztd)#b<?q;yckZ|wZoDqK>0|P7f4hng0T2bNO>Ams)xV8e^JR*2yYtp9A|ICM*zGTS zyi9j<TAj-OWeoQ?-)iwT|6yZk-&3K?xiFwY<;xA0{~sr5n&+wXNXuvBK7MiIYUQ=% z^TkC?YxXsJsNC9_y*)ZV-#fc~foJgIMeFt!J^XO{-~Ha6o<D4S6`Sn^9A;;RXU>oi zsnE08vt`Z0TJ6P))`y0M@kyBk{K?JCe0k*L<=y4weHQg*UkVBm11~N*>V0(cw!dFK z&)fU^`r1gzO2wQH3j0;P_fNZ*<LP-)-?~2b-`DW`KkQ5y#&2Jxa_8-h@%8cPlef1_ z{uScnablrz^6|cBt4wUF7j4+EV%IJ!g9G;u9hxKX>HGZsn=NHN9z8T~@BX#_>w4$k zXK?Ch-C0@YckbTa->S3!X8zXSTeWlNu3ai>r+zK*Z}_$(cCM*_lNuXq$9hdKZ|}p0 zm6@3TsBT`fb}bY0pLRZZ+uxga?tg0^5D>89)Kej+O`A7sYiZqyiQjYV&gsWT)dSL> zKasJK`1AFWYW^R0#tiSby1f4$AGfRcV4$h_^Tx-?Wo6s?`uHvto9EvWsC&0%dHe6V z*5&NHk{cgCpW7k;8vA}&v~$wYDO2L-_~hQ$ka=Z=;I?gMEDvfgt<%%sP~5d^*Q41J zIn9ODeR-zL3yqANId|^kCr>gG^XyVjE!j}~u=u&|4D;{BpY_sK#pLC@`8rX#y?c63 zzyE|aU*FF(P*q*}Sl!RluJg*plQRV-&8&Oh`@eu8->=%6Sy4qpBjH!iOc}oFFDoWq zx;%MOFjMogn*DiO*Y}rudU_UoNQ{n-7VAFx_~SC4xm$|9Mv1QLnmac)=1%X0#m7~$ zWA|0WeJag*wfFq<x{vQ)KGr&QD*szLQ^n<5iBdIt_VVz2iH(ifvUTf{<=@{u-Bx+I z?e6aHb=!+f{ii;E{d#lZ<EoEqp2q8kh6l%QObQJw+&Fvo>r?N;&iwjP{81<SwYa=z zOkA8F$HpyN0;cZz#gH-mgH#t=X=&-H|MhwW4-XxU-26Pn#wYcm^6Q7SSNYCMNkn{n zyXs2y_kEGyrf%FASXK4x7q9f+KWq!QKiD0PWL9jMGHvSLACI4X_$+wzsA|<*D_*%b z+jCw{fAy-OI=iA?k(a^Y;=Os-85p=Inc4vLvPhgB@v+mi{_Yv5-NVB0WYG=&^{JEC zYHIWxcDHkLk=-RDvKOZ|-&rx*Hhw~p=HF*0uc&9Tin@l19t~}AH7U7bQgXE?=WC3c zwdL2%&oq=h8S+iT&OLT=t$pGXn(2FE+ltloDj&38r|2wOb@J=HOUWmk^0)G>;<~BN zpfM-uQb4@+jy?MS-dtO;YSXN=b&Hm*wJO=@KfgbAYKTSAJ6Q%1KgP@zmFNDKzFN5D zMGo8RGU*)i<m(xszUyq585mk8f1hP<zxPFZ<L?=zjRHl_V{Y-+{hnv1Go@I9VL?RE zT+<Md&|H~a|0B~j&S}1|{Zizo_wKXiUU_oIFXK(KY`XCKXJP_Qb|#l++iy8uQ67DB z^@cy&R}@dx`uET2T&(%dv)672I=oJ-yQZ*0_}wfSrFwA=#q&m8<^I+xD}+yNo~T+M z_wjy})$Rp<9@oj&+<D*prm5)v+U5Iyy<YXjNNV!-&40F^u#Ic@)?X>5RCY8)?TKcV zjO53DrLv<2aeoPQ()7z_d1{Dkef91Bw!ep}n-ZnwiHEi3c89$QIQLiN@16ydZtmKB zC|}s=8f#_d%9S0<Gghu#!~I32<&RXIyG`rU{Yxjs>;HQ+wYWXl+-S|SH<xGZseSP) zxxZUm<+8BRJigfaHIKK%o2cb~|7oW3r)*nF@Ur>;@=w2HdArhnJ!fz3%M5w(aG$@H zXFg1h-|2W;=lPr1N)0!K(mCeaf`5MJzEHz+x!_g1_n%WylH3JXL)p%K{PFD2nOsTl z?WsC{e;qo*IDdEX)v2j#f`S99vks@GJ?^akF-73f+XN-si?<I>5fGaH&*jhCTMquB zs@r~aZ*816>FAHrrqK4}KX-F;d#u{-o|?7&|DuXty<e8cX*=bmKJ|b9+T`|m%h!=N zFMM@ZWzR~i{Cci<yPf=#H<{lr`OQu~vutvGtZ%8o)mWQDM>jP8nswpE`~JB6bAC_n z=sSEitTan0wX|3JF|CL7%i5A>GCW2bstU_Ddz&xTyW6uzt^B^F<_?9`OE!uoJLmPs zS~e`d`slb(x7MnuH*{is=Y2Wi7iFVrw)#Wm)*rV;A6MmD$c0Di#~7~L{w3+F)5VEL zmDliC>qy+Yobl|P_sN~Sr`ugVzh-5B&ToAAvQi6AnVI|!vy#6XcQ~GV)*?{1S0U%8 zg>~}WX?#-!iuBiaoK;faC$)6#v8UHLoz~kI7+lN*yLylIs_Y-%<x(teMXoH`*)rkF zni#X$xi^n~0X4Qgr7kVnoN~t~<e6seH}{6dsp~v6xNeJyiqCT4c=`1I!wIeT+RWyr z$#eWTn4fPO?-09vU)Th(xle7b>|5%5>FNVp&9ypJak{bXhd#ZkT6iL2cPG2um5?cG zc&r7Sc&t~fE}rV8_4Cn7Qu|krzBeD|>h^vl^seSxV8E%rUluPvFYI)zU*<_hx~lE! z(BlVGcr_<V8a=CGv68;|QqajSe@{`F_hDw1<#jt$ggDxDKbjU^c`tiG_t$wBN$K<n zY~k65gE=L`gFhepvT34E&#vk29EBT=rtH=0zWPJQ$w`ba-CK9zkwo*I)0V9&Qr*99 z*|xaQr4O%1#{@caTnx)T@n@F9`NF-q=T*|w(w^m8&fQ>RQMGjc?^T>~zVAZ5)h)a$ z(CPBz|No8B`~Ll}uX-7|w(I2HHusbMsb@+h->TGQe10^~;^j;6vUu@p+?<Me$-9m2 zp?0|VPGIYBovoU3<?JyJmyT^x<$HF&ttgMyXP<l~J@t}%X7Zi4J*`TgelJZqImK46 zoKtb$H?@`to3#GzJF(=*nm_r+zH$96O1U&Gvt`16*E<u7mtUB7W`;@GjQQ`k9Jtsr zVI7~D@Nxe67IizC*Iw1$93?t=bK9qMQKM(CqF)L*%}W)#YV+LNf4$yw`_o!xTV5{7 zSA8uRw#oe73`L=A&Rhlt1@KycySidLuRmU%d1PHTpU;O4$}KXTzNd9-_7y~&KX_MH zrTeDzYn7B|-{WhKT)tQF*Cqev?HJ()m8PcoXO>M4u92}`Rm^{MNvimi{Mq-GpFH@- z;-<QqZpyiRCpvapep9n5FXlR@l2#h>d>!`}rIw5pt8y&lrcaC)E7LxGFXDO7Ddm&0 z!IfoPZ#$*@x2Bt`pWJ>;EUou!mTi}RbCtWCV#}`|uD-6iiZ0IX*N)n6HW6^z=KKD2 zTJDz5ch>F|e<$Q*XYhJU;w1kG*S)W+u|MORx!>N%?r&yL-odWIcUdu!_WRoBew=E` zxSIdCT%YIawc<A<U)MZ;Z?|~;nqWCY3j1fa*Ps0U74@su#py)<$?h$@CS9LT?R&ZJ z@6<^9JCPSIMy&pF@^h+uUUp8Ys^~fW|GN1XD;OLe&WJgZ^)ma!jM?+!JUCt^EK#+q zoe*&SVWxD3kkcpQE~)t4oxRKlW-t6<q9Wt3*s{TL&A-j@RlgeU%kZ1EyK;2e&pJ}^ znBha3fv5BHb(`e)dTdLcfBehjbYcQ)obtX;rW-DqZnz}7aZCUG7=9;@IIp@p6L<HR z^D*SJO|ItMe*WHl+qWBfSik6&KKt|e(q_e@^K3NkSZeMt*nKhGS;*;Gt53<R{JV=j zGBg}AtZX@S?zEF<tMX&NCnWUWPCZ5Lzs=c_I^&QzH-qlc51D1k`#yy}()#f>Zt9LX z6HkA*BiFE<>99$LWX2Dl;=nfnzs|o}yK?!u8@Wsj#%Jcwu`i007k008?LE9``N<Ee z`?_vPF`VeElnOE3S=_8%W^idry+D<i>~k5Opl6!@7H?r_klYz}>H5Wp?7R;yp}eA% zW{cJxo-J<V=^TD<`(!o-)=A&5?px-^cK`mLLzk{jx%ujwomh6#^Dg-ZEDhV+lk9Hz zsfZl?Q~dkLukN$;_ruTnWi8(K?z!bo>+W82b;gR<8lN5)WNT#|-sTp2PyYUs;}3uN zl}m0q5q(ZukRiji%cnWQHhw~trSe0UQ<K@DZ6g;KXxr$`m#V&^H@EJ$E$-Q_%T%#i z(~g(n0^gR&`|ovjZudF6rta3i&#yPDvG^F7ZeI29bLMN)wM&+y-22m7#wTC)cfs+l z{P3$+uAH!qXef8E_H4ef@bJP(+wY5>K3gjyTpc?v_uRjlf18^Q2_NtOv#;L&%hnlJ zv#+1F^=T+~*zI-r^75b8*X{jMnBUIVo|S1>9~2gMum1YFqif=~-#U2j+|{e8H!tb; z%h|5$n8>u}?X6HLwx7Hle3c*Fgq#+B@OZJ2^WS6D;JiB?66SUnZXLV0arNgl{`UG> zSryt=6Fs&RU(efq@7}a)e2$Zsxw*y)$2Y%t^{S<P?zRmE({<GT?qpzi8?oE#@R0=v ziXT2)nwt73pWN=AnE&&S6@GqwIc10QUp_cE;ojam5kIC#RPb+EJzaOl*CJCxL(959 zPkLSkb1Evf_w~qH&su%y!<)`ShZenh_38ja{l~}y_v`<idse`qSX1{FYo{;%=8yRL z|HZm$-_Gn;zx7C+x#IGztC7r#DM<khKV~i3vc<&4M#<nnywT}fx3mln)W7&}akKsG z-?#rUv$D26;ukr4?%cW+D+-EhKS~wr^Y@3F&7M(_{dCpV)#0_TUtD;^f0wyJeCu|T zAN}&b9~?ZqWXY4{<Nmj9-n6o^@;HBYPp0#aotNjyy(@orN7f|eNZ<T&A*U84LB$sB zuR9NWozkD{V_Wy<$6|lGxe_7<rKgsd|5(hhW$CwRY_YMiAJ3kc;OxG{Uy?&{>eQ*4 znk&VgJqupub8BPm>uqbLx4-}4sv<PA+%WiQQSwr`$Dlr6O>AhW>EFeXcX!q9sJgm6 z{~NeR`YNtDA|T+v7fEAFnQt!wm6tA8S6$A+=KHhmZdSbf`$>}~J$P_<+qP{wV%^6d z`_8n=eEMpuR*a~%_3a%yq!+sPcZLggx_sUr5fd7@wd(42SJ$JDI)DAD%KezkxF_(f z0k7S?I5xIl>-6+)-HN(&x%zw2?LC=?-`%a=AH8$d@>8F`e!aP4<HMicr}xLLTDNRp z($Q6m9wnKZU!Qt^?ToK4pSMh~E}wj^b-sE_MdkO&IqH8CSFO5omEB=?%k==06{}YV zhlPpN*TQ>zM;}l5a4)MpotJ0LkFwBLd#ms3{62N#hK8+e@!z)Ix;o|ytQGSgu4xo- z@;ZI0?oVOykDncn9trLBo6E-kEqdD*@6ysedrkN32Tgco<nzZdH8_#jVI!lD2h(!! z$>W0J`662nc`!KWb^UGeQp-G$p2D=HddC8ir`?F`<H6?g5<XdqY`XfHRdf2K{CPgL zlfnW5LqY>%Tq9hZ-F=<I&z=Z7pSopouzhx)(Il1+VaZQz^g^z<p9`6KttGd6*DrUb z{hR!bC9Rqj^Ip@oP3KG4>jkSO{AFr5q^ZXHb!*e<-;d7c^{&!do%u{F>((k~@!wy5 z-U#(<RepYt(cz)Ugtl4F|HLns^XfjAwjpo(!7}5r-mt4rP8l;W1XxtA|M~fHcb&wJ z{z!2S#qx7Y|329M{^emO%XUVFF4b@;t*%vNeq86yPk7zD`Sa!OGGEThxCqtrZVV0^ zXT%3^ylRPdlRM#aBKU;GnmbndR))Uk-1VH2<=<G$t}x%;An<A7%zJ+p+8*0|`&3-( z)BUb<SBHH3F8=AwcFWs2y|Rp3<es%B9a$&gTG}WuN$|f$Qh1L|bi}9UqW{+}-^_i= z{@wS3$N$=$(9`&Szv|cO{p-B+7aLYupRVt|)6AOjUt-zA%EZtc+cJ*wJ-y?9@jSQI z%(d13{JuTA%;~pm*U9MR`7^JjpWb43GJ3i7tXFwfrH}u}wtaU*=>a|rp6B<spff&F zJDG9auCDVX;@1uRs>G~XCZtCmHSbe(KUs6i+1K^$O5W+}xst~cY_N0>Wp@9(vi@QD zpItM%{a+s4d?dc3Pp9tV<2xrJDjo#YMK0}6eqOuzZ%?Vo5l|<wu3SUS>}}y(hYN=f zCH&lRuX&ENS?Z$28w)DVo4O~7^S$4h)#Tpo_It;Uq?-p<d@kSQt(EOlVzTUqMeXzV z=Mp!kybt;Jm&rta^5(WzMRh(ObS1f8M8B*Nwk*E0iZShOPeoMBJhAQG=8HeBX0MYq z3_ibTaSy2f6+Zp5B#-95hrv!A+nYPTxa6}3J9*Un68^Y7o7pyW%8f_**VwAO#2#Pg z43q8qSiXI$;VX$U?d*I1x*xqXzcjyUEyvEOQ|<Szzno+Ld`)_)^L2UN{dWuaf+FJf ze!jEzJiBG}t-V_=Ka<$}@=1Jnu&ht1cz=Q6n+5ySOuqeIe0?@_QtOpe-J`o#r0NcD zoG@?d?3t6@=U%OvF~@X?YdYtvmfo|W<aE5WR;>t2+FW8<c}dth^W&5oYYsiX`Y1oV z=k?x)6*0Mc3y$u%r~fuY!)jAS%hben*2C3OXYbT%T5eDLIU%EN?}G<_64R=pS|%Jk z_l)^^+d6wO^?%am){D33%BQEVxqNA%kkh-Tq8lTh90^~%<?4<<R*o;evh%4~oxQno z&hOUpqwm@KMa8BcQN8o?&Ef@9e!q10pReB1BX4=);yJIXu+@Eyo>D<d#wlmMa+H{D zx~$wX=U&CrH`Cg7H{j}<#q!>peCgDp=T|S4YUr$AC*IYw^=iuc)yo#8q~2&0NV?$| zJ9l+R(9H{vZ)`c<GT~o#pNIaOS>Y;?-5)>hOo%wY)qQ>Rxtq`5COk^ZHQCbMx_M_^ zahcZhx`(lfLY*9nEk~<9mL4wGKbsZmbLoS|&y_tp^%l=P!k-&=M_AqV@1b|EoyDp) zPrZ?sy!(_#^P67tV^?o|2yr?Fnl{>-qawWc-BUrQm^D19>$M+GKcl3Q@~~jr6(KK~ zvdP(*tF*#Dz0S&d9U3ZCxA&;1X^TMa);9Ipb(~*huHXLVla!W}_HWu{&@@f>uif5x zGAC}ll>VvDn45oW$wp9@{6>_Z(=MwUD^?Y8Dqa&yTYn}i)aRY)6#LZ^48!kxO&9p2 zvw6j{pWf4*uRi^g9(i;U>x|qzhMWKH5_H<fyE82AYC-Xr%F?&n6|ZwB&i`3DS?5^N zMh?ZVO>XPkmh8MK(aCW!>~UZDcG>rNub(DN`nksEmqu>S?ztNST<Z2u(V4kP{gIyH zk<0g51cJhj-WQ)aWyaM1XK%zUjPLWgWz;M1X@7@x(L0e_!lv`G&gc1M?P<F%9~C{L zbN7c|YpxxBvc~b-#ntyFx^pbFs|ySc^yavDVPa|9c^zKoUC}xc*B&o7?u-?eo$(;i zox@US_O$39H4it;Yu+90A-384n&*i#@Av=eSibk;ug-g$w(nFs@Hs2%-V9&$<v%RS zLY~WYd7jqOxNo-Ce{%EB!cG1@Q77iqP82LJe&bv6?wQCO&oi%9oQoBI;mUC_AoON| zjh^y;oi}0A_HI14bc*{V>t&zbh&XH%`CrF7RrTsEHmRszQtQuOGP@vPzc=ckwQ5Vw z?0eVG-pY8sGrC&;j%rIy!nMr9D)SZAPtS{%nPHvs@85|ZUzU6BWYs>lb9G_r-yd>i z$HK3%tg(}+woqHUEiNH_&F8uMfA{Q*oh{S3dFQ{g^2^t7_V)Um`uRO=**vj)xA^5# z|H;LIX2NC6w2Pj$JUw`EqNk<$qszV4SvpepihUcF&#`6=&{6ZB@^9JiZ;$qDI`&M@ z%JAy7%P|@Px`j7lB7<~iu3LBb_LN_$vk!Z9pSx%F?EJB?>xNh3>bcLWv1KIt=q0U8 zXA$B&9?YSb!?*hXo9S}OUuHi(_-q4*;z#$%68SO=_juGYU)%}3X8Zq!bGh7oeT5dD z$Oop6wBwnzW0|$@3VQ$karUc1%af%~j?3;m4e1r`T(G0|+rM|2?WsBo@>d!^pRdq- zU9Pj@(}IHMOCB70BP99y9QVu@SMKj}eay(vnp`A(3EagCj`yy2QwB{cfBf~Yx;A~s zj-Ikh+ph@v?<~~$d8)DHmR4lG^vS@q+m+ELA{ZF%@wC0aUQqCH<_i0Kts0Yi!PQ39 zm7)w9Vuzn!>iKahymR$~?bV@=irn-LGyh=7XKl;8V07Wb%x8;kEc`P6YILxF?8e(H z3~4j$naiJSvQz8()g{&L>Oc9Rca7*)Q-%q`pG{U|6+LJ3f0M98^S{Cu9jkMe5=+hm z{|Po`1oiQ@U&hkM+uk|dkNLoCmG|DieCG1(+yAq5>1xf*SKrp^Tsv}3)cyb`Lq7k} znhkS3G`fC1|JM0ceD?o+>u1fq;#Pb2d~s2^nDl!Gh7Z>QpB#U9E#yjDZtt!=_WMru zAO1S`ol(lf?Q_DF7%o(a%w*eGwNK$|k=vopDeC-OT3xHOx>k2|WV~3B`C^si&6i(g zp5EBHzjuzjD>K7d-;bFL4P^`F{`u<XvnMqx?d#=l^W*26Dke-?IdiH_{<*&|0`Hx; z`1t7^jsv@w&Ryd8=EB2(legb@J$+`^)wx&iyxHON?mTi<PSM`p?=CX#@xB!*HP7zs z{xaRLs#6OOFN}&RvekV3=4P?|`y1N|4%+N=XaAs=8J;Qe#9YDR$x&%fj@CoU3y-V) z=%4Phvrswl&JTxdY4_vn&TY2)yJy9Uho5C#lrEl&-F>&JIy%al#dnsJXsK_}&kdEA z+v;jRF4C`fzh$+F4-c1(xLjP+wGaEI241|rN=uuaS4!jGwk=yq9zA(^cel0s9DC_1 ziya$QWL$i-^ikyPx?h#&@BMv!ZB5S}0ket;_a`ll_ujU0&6+!6_FN9q+2Q)p1+SlG zB_$R8`EgS6@^T?3Cq7w8>oSw@r4Mfkx3;=oy?V8g@t>I3vz7__|NohL_Mw2&k3Y9; ztLvlx|CO@e&)6csUHtjYoH=`|zi<EQ&wODT@tw0(F?xzB*4DchEjo1e>(T5pdu={& zUiq*uJ3sS-y#2R>&F!9^Cy)2d-?DjgX-Ub1dAlnww|yvHZfkqz{hgiG87Deq?cb}k zaJVWtaZEowRcG0fJL~+GF-T<OXI{8^RrG!jk7bF=uPKcJL6MO&Cr!$N%(%(k-kx`R zSK;rzco(IKmEy*sdgfuT4A1@e(Xvg#`atv&*?*NhTwF8klGWM|%h_fv`SNASlPL!l zXx?8R{r2_a*q|UGnVK8du1!0d^s!=(X0ZC&n7v`GtCP~xrNzsYzr5JEP1^22^g`KX z2an%AeZb-V)uXP_zn4DO{7Tvs+GjH<y93dT>lbDOgomqF&iQnxwR>~g`I8khP91W; zcKG)y*?Fc08y?*bUHSc8?dCVy$;peqd^z(~+U(a)UI+09wQZZ(oH#UfwSRv+e)i#W z<*sh;FIJ^eHaGHbUedpM_2ai|AO1N>F*GdNYg@rd_X#stXNu1AbfeZ%yzy%^2uFjE z@>R_A8?M1!!g!sH4^a`?`pkpjfp5abh_jJvE}AH?Fuc9=y4}oFOn)h(B|`<jr~Hpe zJ{k)-7!(v&I&!}=4Y<zUusz=Ry}n0wn3MohLwOX4y?8mJE<?usILl-4`mBd<Psm_D zV7=sIG0RE8yG^$ztYA2>yRS+lxccIkT#q@940|q1%+d6yHs$S=eQxoO@t&?x-_7tS zhuoG+uQ$)$`87?CfgyM4M&b5j=fsa(J}RvFU22A@6B`@<9EOHJQr0=D><V8iCp_x( zwQ;)WbzR)zIzz?eS;ef1wWmHP@%qlQcp%4ez`DJvOu_c`S2qu)kFQu=ljF_JTDkTz zR2)vR7y9`tX}!zCsljX$JzVzlYNjj9s=MOyEr(&j#KIWU&ns&FK5HrwiQCJox!0+f zN%67H(wU20q!{k;NS4b;cQ<*cWbIfG5R~-emp4Pk`VaRe3~*xjP{wI3Uib0R(`|CB z43`dcteiQuH}?87pPZF*t;_%CpU*GKb8)Kj;F6TvV?X6q6~l)~_5SktuN4^t=9n@t z$X>dj<#Tq8&EDVh>}rqQy?p)JzvfJ1yUK5C9E?sMz54jpR*Cs`%sOjj|FH3LTZ`-M zUGzoOAz8Ze=)=Pcng6y$-M08v@bd3h^ZQ{TAzMmT{Qp;d?eOaUslCnrTRQ*${a$f> z{r}?9&s#RWwko}K+<%_kRGpgVd6%ZFl(#G^-L~<yRawn}r`qAFo98`yUcWJ6V==!u zw{~^8|NXPkbwV60zUL;{{<ysS{1<718;4HSEx3Ondi(nsGjDsu3mZ!Fm<V6G5XHsC zwLSNL<&h7GX>+aJ-QuD?zV$k}=F+B3=b!6+`1EDQ1A9GN<>F^+&aaQ_&3oyl;?yq} z|K;hWO`o32*P7fteE0AA{r_ivKe}id-`C}D_xDKHow;?(>RZ*F7l!|i_s^Fx&)d>k zIlX(jo__qr4VQ11zw48<R<u-2ZTkO1bF#YKsk5_<zAB$&{CQG+bHAK*Vsh@^muvdJ ze)$5LIq92UZf5Cy?18d=+^?K-f9}k=bKn4{ZS}Vqrmu?^253kcKR)PC{M1HI#F2Yu z$+j)qN+%g!T(WtoXZq<iZ*nGjeED%wc=EYveX(<wrqAWIR{!_y!a`-Wxw_42zPT6O zme|(JsC)Ee<(@tNkKC{N{mp#)mc@B*zZ!af`*gqlf2Yf$rY5J4+gn>(l_qM~|DWlZ zewu&R&W`CkvrMio*_>MPW$T$WYtF1$vpRgSuT^xPthmCw?Ck%ID`$pAM(*@bS+(+^ zylvT|cXyYlrJt1ebEA+^ZLY5WJR9AAW=}2%zLanLn6O}Gf%K-WD^{(VRsPb6!_dg& z$;XP+)Tfgob;PnA{?|QP&(8ZvIbLsX`TII=bEU-G+|Zz)qAxc-{?6ntDlRfM-W+8W zBG;duljFnj@``8ppSA1O=_$Iz$M*{a#m4H!y?J&vx@AJc0?kXW?J8#I{d+XIKRxIE z$L{v!>!bC<pXc5E_5JnZCr@rX(UENS_w&sC@z><fA~wB$MJrSE9v^ftR^;_rv3hlQ zXz0}sKUc-9tMJOq)Kqlw_72{}(|vT(M%IZQS3a-`o{Wh2=5{1(ZQS<v+wa@|`Oti@ znXOOOHtXB-&skYnQQtmqIkMime8Ua>b<R_#SUl37R<pC<#)X68O8Tnm>hEuE&VRg2 zms|Wy{GJ!wH#ev7#3=}Dh|n?H{m}eCTA*H?BoEsx&hJt)UfkTg+e5{w#v;V%>HB8I z7J=~T^Ug-bstC=suXp@Y8WCZkc;w>2#*Ybn|AY@EZS<3|wyD1-<L>_Z+Uusx#pX^O z%ced1km%gTFa7A*t4XtGuRao})G}qd{eSfz0YOEl{#4F?|MUJjZt+7LiuLk;+`sAE zY~H?gt6-<gB=v^ajy)Rx6Bhg|xOU*kr}fj-R8;CV|Jl7deDT_~y6^9Lckik2jE;W2 zTD5!jW~<p}<9>bpG~>o=r-dIbJPdF;kv{)yl8wY?y|nM|mizwCST=ca@{gY!p`lm9 zRvn&nl>5=6NA^EczU?SX-m-P8|J;A(`tSEoy}wqWWyR{%Z|`iiR#*RiY3b>(urR}o z*EtpU-ib*)Kgsq-q_O=h>->jzD!J8v^b2>n2>zE3u4H4@ZMZ$*OiD`1xw+d9%n`Cx zVqjq00y-C9XM40b_iZ`7z2bWRUR_*lbMj93yPuJ_t!9>Nn=-HT;i04Z{<23#-R74u zdGqHd_Z8999G56BuU9J!|Ak%S+iP3nH}}`|wcD?2|6Y{0cH_cR|I8F0K0D%hS!T|z z$eR|wc;)1ZUUZ~fTkKvrDZV2*e|>27wa~CIaK1gdU2bpf@A8cs-r6UeIC~_TOOnS# zSo?Y5!kH8EqS;^BCS|1^ef&{wnd<hh4)@Ax>fY}C{XI8#&DAScI28Nkp6;yvB_%0& zw_~yW1@5j^?yhM!cjX?xmV0~V+S$`*EB;-(a^}<~wyXC#>I3Wl))riSRXS~&m@^yy zs`cybi_LljgbWgG9^b#cs5M?E$|C+^bME$nYaf<9T(j_}6Q8W*hvV@xXGS_T9=LSM zNTcA;m(1W<pI7jn;Ll`W;IgUUB<n~6YP4+svoBicbm>cQtpx)E1B0ilpUXO@geCwH C$Q?=m literal 0 HcmV?d00001 diff --git a/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-unpin-2-linux.png b/playwright/snapshots/pinned-messages/pinned-messages.spec.ts/pinned-messages-list-unpin-2-linux.png new file mode 100644 index 0000000000000000000000000000000000000000..4eede005d886b1dc170f92b78cc32ae3692362ab GIT binary patch literal 13658 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 literal 0 HcmV?d00001 diff --git a/res/css/_components.pcss b/res/css/_components.pcss index 96c285bc0a..bfcab19879 100644 --- a/res/css/_components.pcss +++ b/res/css/_components.pcss @@ -298,6 +298,7 @@ @import "./views/rooms/_NewRoomIntro.pcss"; @import "./views/rooms/_NotificationBadge.pcss"; @import "./views/rooms/_PinnedEventTile.pcss"; +@import "./views/rooms/_PinnedMessageBanner.pcss"; @import "./views/rooms/_PresenceLabel.pcss"; @import "./views/rooms/_ReadReceiptGroup.pcss"; @import "./views/rooms/_ReplyPreview.pcss"; diff --git a/res/css/views/rooms/_PinnedMessageBanner.pcss b/res/css/views/rooms/_PinnedMessageBanner.pcss new file mode 100644 index 0000000000..c6889aba75 --- /dev/null +++ b/res/css/views/rooms/_PinnedMessageBanner.pcss @@ -0,0 +1,119 @@ +/* + * 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. + */ + +.mx_PinnedMessageBanner { + display: flex; + align-items: center; + justify-content: space-between; + gap: var(--cpd-space-4x); + /* 80px = 79px + 1px from the bottom border */ + height: 79px; + padding: 0 var(--cpd-space-4x); + + background-color: var(--cpd-color-bg-canvas-default); + border-bottom: 1px solid var(--cpd-color-gray-400); + + /* From figma */ + box-shadow: 0 var(--cpd-space-2x) var(--cpd-space-6x) calc(var(--cpd-space-2x) * -1) rgba(27, 29, 34, 0.1); + + .mx_PinnedMessageBanner_main { + background: transparent; + border: none; + text-align: start; + cursor: pointer; + + height: 100%; + flex-grow: 1; + display: flex; + align-items: center; + + .mx_PinnedMessageBanner_content { + display: grid; + grid-template: + "indicators pinIcon title" auto + "indicators pinIcon message" auto; + column-gap: var(--cpd-space-2x); + } + + .mx_PinnedMessageBanner_Indicators { + grid-area: indicators; + display: flex; + flex-direction: column; + gap: var(--cpd-space-0-5x); + height: 100%; + + .mx_PinnedMessageBanner_Indicator { + width: var(--cpd-space-0-5x); + background-color: var(--cpd-color-gray-600); + height: 100%; + } + + .mx_PinnedMessageBanner_Indicator--active { + background-color: var(--cpd-color-icon-accent-primary); + } + + .mx_PinnedMessageBanner_Indicator--hidden { + background-color: transparent; + } + } + + .mx_PinnedMessageBanner_PinIcon { + grid-area: pinIcon; + align-self: center; + fill: var(--cpd-color-icon-secondary-alpha); + } + + .mx_PinnedMessageBanner_title { + grid-area: title; + font: var(--cpd-font-body-sm-regular); + color: var(--cpd-color-text-action-accent); + height: 20px; + + .mx_PinnedMessageBanner_title_counter { + font: var(--cpd-font-body-sm-semibold); + } + } + + .mx_PinnedMessageBanner_message { + grid-area: message; + font: var(--cpd-font-body-sm-regular); + height: 20px; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } + + .mx_PinnedMessageBanner_redactedMessage { + grid-area: message; + height: 20px; + display: flex; + align-items: center; + } + } + + .mx_PinnedMessageBanner_actions { + white-space: nowrap; + } +} + +.mx_PinnedMessageBanner[data-single-message="true"] { + /* 64px = 63px + 1px from the bottom border */ + height: 63px; + + .mx_PinnedMessageBanner_content { + grid-template: "pinIcon message" auto; + } +} diff --git a/src/components/structures/RoomView.tsx b/src/components/structures/RoomView.tsx index 70ee16b542..9c7469346d 100644 --- a/src/components/structures/RoomView.tsx +++ b/src/components/structures/RoomView.tsx @@ -133,6 +133,7 @@ import { SubmitAskToJoinPayload } from "../../dispatcher/payloads/SubmitAskToJoi import RightPanelStore from "../../stores/right-panel/RightPanelStore"; import { onView3pidInvite } from "../../stores/right-panel/action-handlers"; import RoomSearchAuxPanel from "../views/rooms/RoomSearchAuxPanel"; +import { PinnedMessageBanner } from "../views/rooms/PinnedMessageBanner"; const DEBUG = false; const PREVENT_MULTIPLE_JITSI_WITHIN = 30_000; @@ -2409,6 +2410,14 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> { </AuxPanel> ); + const isPinningEnabled = SettingsStore.getValue<boolean>("feature_pinning"); + let pinnedMessageBanner; + if (isPinningEnabled) { + pinnedMessageBanner = ( + <PinnedMessageBanner room={this.state.room} permalinkCreator={this.permalinkCreator} /> + ); + } + let messageComposer; const showComposer = // joined and not showing search results @@ -2537,6 +2546,7 @@ export class RoomView extends React.Component<IRoomProps, IRoomState> { <Measured sensor={this.roomViewBody.current} onMeasurement={this.onMeasurement} /> )} {auxPanel} + {pinnedMessageBanner} <main className={timelineClasses}> <FileDropTarget parent={this.roomView.current} onFileDrop={this.onFileDrop} /> {topUnreadMessagesBar} diff --git a/src/components/views/context_menus/RoomContextMenu.tsx b/src/components/views/context_menus/RoomContextMenu.tsx index 0dbd4b5395..6c105dd0cc 100644 --- a/src/components/views/context_menus/RoomContextMenu.tsx +++ b/src/components/views/context_menus/RoomContextMenu.tsx @@ -35,7 +35,6 @@ import { RoomNotifState } from "../../../RoomNotifs"; import Modal from "../../../Modal"; import ExportDialog from "../dialogs/ExportDialog"; import { useFeatureEnabled } from "../../../hooks/useSettings"; -import { usePinnedEvents } from "../right_panel/PinnedMessagesCard"; import { RightPanelPhases } from "../../../stores/right-panel/RightPanelStorePhases"; import { RoomSettingsTab } from "../dialogs/RoomSettingsDialog"; import { useEventEmitterState } from "../../../hooks/useEventEmitter"; @@ -53,6 +52,7 @@ import { UIComponent } from "../../../settings/UIFeature"; import { DeveloperToolsOption } from "./DeveloperToolsOption"; import { tagRoom } from "../../../utils/room/tagRoom"; import { useIsVideoRoom } from "../../../utils/video-rooms"; +import { usePinnedEvents } from "../../../hooks/usePinnedEvents"; interface IProps extends IContextMenuProps { room: Room; diff --git a/src/components/views/right_panel/LegacyRoomHeaderButtons.tsx b/src/components/views/right_panel/LegacyRoomHeaderButtons.tsx index 207c97ec7b..c3fc1fe95d 100644 --- a/src/components/views/right_panel/LegacyRoomHeaderButtons.tsx +++ b/src/components/views/right_panel/LegacyRoomHeaderButtons.tsx @@ -28,7 +28,6 @@ import HeaderButtons, { HeaderKind } from "./HeaderButtons"; import { RightPanelPhases } from "../../../stores/right-panel/RightPanelStorePhases"; import { ActionPayload } from "../../../dispatcher/payloads"; import RightPanelStore from "../../../stores/right-panel/RightPanelStore"; -import { useReadPinnedEvents, usePinnedEvents } from "./PinnedMessagesCard"; import { showThreadPanel } from "../../../dispatcher/dispatch-actions/threads"; import SettingsStore from "../../../settings/SettingsStore"; import { @@ -40,6 +39,7 @@ import { SummarizedNotificationState } from "../../../stores/notifications/Summa import PosthogTrackers from "../../../PosthogTrackers"; import { ButtonEvent } from "../elements/AccessibleButton"; import { doesRoomOrThreadHaveUnreadMessages } from "../../../Unread"; +import { usePinnedEvents, useReadPinnedEvents } from "../../../hooks/usePinnedEvents"; const ROOM_INFO_PHASES = [ RightPanelPhases.RoomSummary, diff --git a/src/components/views/right_panel/PinnedMessagesCard.tsx b/src/components/views/right_panel/PinnedMessagesCard.tsx index 85be2e6d03..0f1f856786 100644 --- a/src/components/views/right_panel/PinnedMessagesCard.tsx +++ b/src/components/views/right_panel/PinnedMessagesCard.tsx @@ -14,17 +14,8 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, { useCallback, useEffect, useState, JSX } from "react"; -import { - Room, - RoomEvent, - RoomStateEvent, - MatrixEvent, - EventType, - RelationType, - EventTimeline, -} from "matrix-js-sdk/src/matrix"; -import { logger } from "matrix-js-sdk/src/logger"; +import React, { useCallback, useEffect, JSX } from "react"; +import { Room, MatrixEvent, EventType } from "matrix-js-sdk/src/matrix"; import { Button, Separator } from "@vector-im/compound-web"; import classNames from "classnames"; import PinIcon from "@vector-im/compound-design-tokens/assets/web/icons/pin"; @@ -33,9 +24,6 @@ import { _t } from "../../../languageHandler"; import BaseCard from "./BaseCard"; import Spinner from "../elements/Spinner"; import { useMatrixClientContext } from "../../../contexts/MatrixClientContext"; -import { useTypedEventEmitter } from "../../../hooks/useEventEmitter"; -import PinningUtils from "../../../utils/PinningUtils"; -import { useAsyncMemo } from "../../../hooks/useAsyncMemo"; import { PinnedEventTile } from "../rooms/PinnedEventTile"; import { useRoomState } from "../../../hooks/useRoomState"; import RoomContext, { TimelineRenderingType, useRoomContext } from "../../../contexts/RoomContext"; @@ -46,155 +34,7 @@ import { filterBoolean } from "../../../utils/arrays"; import Modal from "../../../Modal"; import { UnpinAllDialog } from "../dialogs/UnpinAllDialog"; import EmptyState from "./EmptyState"; - -/** - * Get the pinned event IDs from a room. - * @param room - */ -function getPinnedEventIds(room?: Room): string[] { - return ( - room - ?.getLiveTimeline() - .getState(EventTimeline.FORWARDS) - ?.getStateEvents(EventType.RoomPinnedEvents, "") - ?.getContent()?.pinned ?? [] - ); -} - -/** - * Get the pinned event IDs from a room. - * @param room - */ -export const usePinnedEvents = (room?: Room): string[] => { - const [pinnedEvents, setPinnedEvents] = useState<string[]>(getPinnedEventIds(room)); - - // Update the pinned events when the room state changes - // Filter out events that are not pinned events - const update = useCallback( - (ev?: MatrixEvent) => { - if (ev && ev.getType() !== EventType.RoomPinnedEvents) return; - setPinnedEvents(getPinnedEventIds(room)); - }, - [room], - ); - - useTypedEventEmitter(room?.getLiveTimeline().getState(EventTimeline.FORWARDS), RoomStateEvent.Events, update); - useEffect(() => { - setPinnedEvents(getPinnedEventIds(room)); - return () => { - setPinnedEvents([]); - }; - }, [room]); - return pinnedEvents; -}; - -/** - * Get the read pinned event IDs from a room. - * @param room - */ -function getReadPinnedEventIds(room?: Room): Set<string> { - return new Set(room?.getAccountData(ReadPinsEventId)?.getContent()?.event_ids ?? []); -} - -/** - * Get the read pinned event IDs from a room. - * @param room - */ -export const useReadPinnedEvents = (room?: Room): Set<string> => { - const [readPinnedEvents, setReadPinnedEvents] = useState<Set<string>>(new Set()); - - // Update the read pinned events when the room state changes - // Filter out events that are not read pinned events - const update = useCallback( - (ev?: MatrixEvent) => { - if (ev && ev.getType() !== ReadPinsEventId) return; - setReadPinnedEvents(getReadPinnedEventIds(room)); - }, - [room], - ); - - useTypedEventEmitter(room, RoomEvent.AccountData, update); - useEffect(() => { - setReadPinnedEvents(getReadPinnedEventIds(room)); - return () => { - setReadPinnedEvents(new Set()); - }; - }, [room]); - return readPinnedEvents; -}; - -/** - * Fetch the pinned events - * @param room - * @param pinnedEventIds - */ -function useFetchedPinnedEvents(room: Room, pinnedEventIds: string[]): Array<MatrixEvent | null> | null { - const cli = useMatrixClientContext(); - - return useAsyncMemo( - () => { - const promises = pinnedEventIds.map(async (eventId): Promise<MatrixEvent | null> => { - const timelineSet = room.getUnfilteredTimelineSet(); - // Get the event from the local timeline - const localEvent = timelineSet - ?.getTimelineForEvent(eventId) - ?.getEvents() - .find((e) => e.getId() === eventId); - - // Decrypt the event if it's encrypted - // Can happen when the tab is refreshed and the pinned events card is opened directly - if (localEvent?.isEncrypted()) { - await cli.decryptEventIfNeeded(localEvent); - } - - // If the event is available locally, return it if it's pinnable - // Otherwise, return null - if (localEvent) return PinningUtils.isPinnable(localEvent) ? localEvent : null; - - try { - // The event is not available locally, so we fetch the event and latest edit in parallel - const [ - evJson, - { - events: [edit], - }, - ] = await Promise.all([ - cli.fetchRoomEvent(room.roomId, eventId), - cli.relations(room.roomId, eventId, RelationType.Replace, null, { limit: 1 }), - ]); - - const event = new MatrixEvent(evJson); - - // Decrypt the event if it's encrypted - if (event.isEncrypted()) { - await cli.decryptEventIfNeeded(event); - } - - // Handle poll events - await room.processPollEvents([event]); - - const senderUserId = event.getSender(); - if (senderUserId && PinningUtils.isPinnable(event)) { - // Inject sender information - event.sender = room.getMember(senderUserId); - // Also inject any edits we've found - if (edit) event.makeReplaced(edit); - - return event; - } - } catch (err) { - logger.error("Error looking up pinned event " + eventId + " in room " + room.roomId); - logger.error(err); - } - return null; - }); - - return Promise.all(promises); - }, - [cli, room, pinnedEventIds], - null, - ); -} +import { useFetchedPinnedEvents, usePinnedEvents, useReadPinnedEvents } from "../../../hooks/usePinnedEvents"; /** * List the pinned messages in a room inside a Card. diff --git a/src/components/views/right_panel/RoomSummaryCard.tsx b/src/components/views/right_panel/RoomSummaryCard.tsx index 9dfe049a52..ece150495e 100644 --- a/src/components/views/right_panel/RoomSummaryCard.tsx +++ b/src/components/views/right_panel/RoomSummaryCard.tsx @@ -58,7 +58,6 @@ import { E2EStatus } from "../../../utils/ShieldUtils"; import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks"; import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext"; import { useFeatureEnabled } from "../../../hooks/useSettings"; -import { usePinnedEvents } from "./PinnedMessagesCard"; import RoomName from "../elements/RoomName"; import ExportDialog from "../dialogs/ExportDialog"; import RightPanelStore from "../../../stores/right-panel/RightPanelStore"; @@ -81,6 +80,7 @@ import { Action } from "../../../dispatcher/actions"; import { Key } from "../../../Keyboard"; import { useTransition } from "../../../hooks/useTransition"; import { useIsVideoRoom } from "../../../utils/video-rooms"; +import { usePinnedEvents } from "../../../hooks/usePinnedEvents"; interface IProps { room: Room; diff --git a/src/components/views/rooms/PinnedMessageBanner.tsx b/src/components/views/rooms/PinnedMessageBanner.tsx new file mode 100644 index 0000000000..f7010b8838 --- /dev/null +++ b/src/components/views/rooms/PinnedMessageBanner.tsx @@ -0,0 +1,252 @@ +/* + * 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. + */ + +import React, { JSX, useEffect, useMemo, useState } from "react"; +import { Icon as PinIcon } from "@vector-im/compound-design-tokens/icons/pin-solid.svg"; +import { Button } from "@vector-im/compound-web"; +import { Room } from "matrix-js-sdk/src/matrix"; +import classNames from "classnames"; + +import { usePinnedEvents, useSortedFetchedPinnedEvents } from "../../../hooks/usePinnedEvents"; +import { _t } from "../../../languageHandler"; +import RightPanelStore from "../../../stores/right-panel/RightPanelStore"; +import { RightPanelPhases } from "../../../stores/right-panel/RightPanelStorePhases"; +import { useEventEmitter } from "../../../hooks/useEventEmitter"; +import { UPDATE_EVENT } from "../../../stores/AsyncStore"; +import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks"; +import { MessagePreviewStore } from "../../../stores/room-list/MessagePreviewStore"; +import dis from "../../../dispatcher/dispatcher"; +import { ViewRoomPayload } from "../../../dispatcher/payloads/ViewRoomPayload"; +import { Action } from "../../../dispatcher/actions"; +import MessageEvent from "../messages/MessageEvent"; + +/** + * The props for the {@link PinnedMessageBanner} component. + */ +interface PinnedMessageBannerProps { + /** + * The permalink creator to use. + */ + permalinkCreator: RoomPermalinkCreator; + /** + * The room where the banner is displayed + */ + room: Room; +} + +/** + * A banner that displays the pinned messages in a room. + */ +export function PinnedMessageBanner({ room, permalinkCreator }: PinnedMessageBannerProps): JSX.Element | null { + const pinnedEventIds = usePinnedEvents(room); + const pinnedEvents = useSortedFetchedPinnedEvents(room, pinnedEventIds); + const eventCount = pinnedEvents.length; + const isSinglePinnedEvent = eventCount === 1; + + const [currentEventIndex, setCurrentEventIndex] = useState(eventCount - 1); + // If the list of pinned events changes, we need to make sure the current index isn't out of bound + useEffect(() => { + setCurrentEventIndex((currentEventIndex) => { + // If the current index is out of bound, we set it to the last index + if (currentEventIndex < 0 || currentEventIndex >= eventCount) return eventCount - 1; + return currentEventIndex; + }); + }, [eventCount]); + + const pinnedEvent = pinnedEvents[currentEventIndex]; + // Generate a preview for the pinned event + const eventPreview = useMemo(() => { + if (!pinnedEvent || pinnedEvent.isRedacted() || pinnedEvent.isDecryptionFailure()) return null; + return MessagePreviewStore.instance.generatePreviewForEvent(pinnedEvent); + }, [pinnedEvent]); + + if (!pinnedEvent) return null; + + const shouldUseMessageEvent = pinnedEvent.isRedacted() || pinnedEvent.isDecryptionFailure(); + + const onBannerClick = (): void => { + // Scroll to the pinned message + dis.dispatch<ViewRoomPayload>({ + action: Action.ViewRoom, + event_id: pinnedEvent.getId(), + highlighted: true, + room_id: room.roomId, + metricsTrigger: undefined, // room doesn't change + }); + + // Cycle through the pinned messages + // When we reach the first message, we go back to the last message + setCurrentEventIndex((currentEventIndex) => (--currentEventIndex === -1 ? eventCount - 1 : currentEventIndex)); + }; + + return ( + <div + className="mx_PinnedMessageBanner" + data-single-message={isSinglePinnedEvent} + aria-label={_t("room|pinned_message_banner|description")} + data-testid="pinned-message-banner" + > + <button + aria-label={_t("room|pinned_message_banner|go_to_message")} + type="button" + className="mx_PinnedMessageBanner_main" + onClick={onBannerClick} + > + <div className="mx_PinnedMessageBanner_content"> + {!isSinglePinnedEvent && <Indicators count={eventCount} currentIndex={currentEventIndex} />} + <PinIcon width="20" className="mx_PinnedMessageBanner_PinIcon" /> + {!isSinglePinnedEvent && ( + <div className="mx_PinnedMessageBanner_title" data-testid="banner-counter"> + {_t( + "room|pinned_message_banner|title", + { + index: currentEventIndex + 1, + length: eventCount, + }, + { bold: (sub) => <span className="mx_PinnedMessageBanner_title_counter">{sub}</span> }, + )} + </div> + )} + {eventPreview && <span className="mx_PinnedMessageBanner_message">{eventPreview}</span>} + {/* In case of redacted event, we want to display the nice sentence of the message event like in the timeline or in the pinned message list */} + {shouldUseMessageEvent && ( + <div className="mx_PinnedMessageBanner_redactedMessage"> + <MessageEvent + mxEvent={pinnedEvent} + maxImageHeight={20} + permalinkCreator={permalinkCreator} + replacingEventId={pinnedEvent.replacingEventId()} + /> + </div> + )} + </div> + </button> + {!isSinglePinnedEvent && <BannerButton room={room} />} + </div> + ); +} + +const MAX_INDICATORS = 3; + +/** + * The props for the {@link IndicatorsProps} component. + */ +interface IndicatorsProps { + /** + * The number of messages pinned + */ + count: number; + /** + * The current index of the pinned message + */ + currentIndex: number; +} + +/** + * A component that displays vertical indicators for the pinned messages. + */ +function Indicators({ count, currentIndex }: IndicatorsProps): JSX.Element { + // We only display a maximum of 3 indicators at one time. + // When there is more than 3 messages pinned, we will cycle through the indicators + + // If there is only 2 messages pinned, we will display 2 indicators + // In case of 1 message pinned, the indicators are not displayed, see {@link PinnedMessageBanner} logic. + const numberOfIndicators = Math.min(count, MAX_INDICATORS); + // The index of the active indicator + const index = currentIndex % numberOfIndicators; + + // We hide the indicators when we are on the last cycle and there are less than 3 remaining messages pinned + const numberOfCycles = Math.ceil(count / numberOfIndicators); + // If the current index is greater than the last cycle index, we are on the last cycle + const isLastCycle = currentIndex >= (numberOfCycles - 1) * MAX_INDICATORS; + // The index of the last message in the last cycle + const lastCycleIndex = numberOfIndicators - (numberOfCycles * numberOfIndicators - count); + + return ( + <div className="mx_PinnedMessageBanner_Indicators"> + {Array.from({ length: numberOfIndicators }).map((_, i) => ( + <Indicator key={i} active={i === index} hidden={isLastCycle && lastCycleIndex <= i} /> + ))} + </div> + ); +} + +/** + * The props for the {@link Indicator} component. + */ +interface IndicatorProps { + /** + * Whether the indicator is active + */ + active: boolean; + /** + * Whether the indicator is hidden + */ + hidden: boolean; +} + +/** + * A component that displays a vertical indicator for a pinned message. + */ +function Indicator({ active, hidden }: IndicatorProps): JSX.Element { + return ( + <div + data-testid="banner-indicator" + className={classNames("mx_PinnedMessageBanner_Indicator", { + "mx_PinnedMessageBanner_Indicator--active": active, + "mx_PinnedMessageBanner_Indicator--hidden": hidden, + })} + /> + ); +} + +function getRightPanelPhase(roomId: string): RightPanelPhases | null { + if (!RightPanelStore.instance.isOpenForRoom(roomId)) return null; + return RightPanelStore.instance.currentCard.phase; +} + +/** + * The props for the {@link BannerButton} component. + */ +interface BannerButtonProps { + /** + * The room where the banner is displayed + */ + room: Room; +} + +/** + * A button that allows the user to view or close the list of pinned messages. + */ +function BannerButton({ room }: BannerButtonProps): JSX.Element { + const [currentPhase, setCurrentPhase] = useState<RightPanelPhases | null>(getRightPanelPhase(room.roomId)); + useEventEmitter(RightPanelStore.instance, UPDATE_EVENT, () => setCurrentPhase(getRightPanelPhase(room.roomId))); + const isPinnedMessagesPhase = currentPhase === RightPanelPhases.PinnedMessages; + + return ( + <Button + className="mx_PinnedMessageBanner_actions" + kind="tertiary" + onClick={() => { + RightPanelStore.instance.showOrHidePhase(RightPanelPhases.PinnedMessages); + }} + > + {isPinnedMessagesPhase + ? _t("room|pinned_message_banner|button_close_list") + : _t("room|pinned_message_banner|button_view_all")} + </Button> + ); +} diff --git a/src/hooks/usePinnedEvents.ts b/src/hooks/usePinnedEvents.ts new file mode 100644 index 0000000000..eb53151138 --- /dev/null +++ b/src/hooks/usePinnedEvents.ts @@ -0,0 +1,212 @@ +/* + * 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. + */ + +import { useCallback, useEffect, useMemo, useState } from "react"; +import { + Room, + RoomEvent, + RoomStateEvent, + MatrixEvent, + EventType, + RelationType, + EventTimeline, + MatrixClient, +} from "matrix-js-sdk/src/matrix"; +import { logger } from "matrix-js-sdk/src/logger"; + +import { useTypedEventEmitter } from "./useEventEmitter"; +import { ReadPinsEventId } from "../components/views/right_panel/types"; +import { useMatrixClientContext } from "../contexts/MatrixClientContext"; +import { useAsyncMemo } from "./useAsyncMemo"; +import PinningUtils from "../utils/PinningUtils"; + +/** + * Get the pinned event IDs from a room. + * @param room + */ +function getPinnedEventIds(room?: Room): string[] { + return ( + room + ?.getLiveTimeline() + .getState(EventTimeline.FORWARDS) + ?.getStateEvents(EventType.RoomPinnedEvents, "") + ?.getContent()?.pinned ?? [] + ); +} + +/** + * Get the pinned event IDs from a room. + * @param room + */ +export const usePinnedEvents = (room?: Room): string[] => { + const [pinnedEvents, setPinnedEvents] = useState<string[]>(getPinnedEventIds(room)); + + // Update the pinned events when the room state changes + // Filter out events that are not pinned events + const update = useCallback( + (ev?: MatrixEvent) => { + if (ev && ev.getType() !== EventType.RoomPinnedEvents) return; + setPinnedEvents(getPinnedEventIds(room)); + }, + [room], + ); + + useTypedEventEmitter(room?.getLiveTimeline().getState(EventTimeline.FORWARDS), RoomStateEvent.Events, update); + useEffect(() => { + setPinnedEvents(getPinnedEventIds(room)); + return () => { + setPinnedEvents([]); + }; + }, [room]); + return pinnedEvents; +}; + +/** + * Get the read pinned event IDs from a room. + * @param room + */ +function getReadPinnedEventIds(room?: Room): Set<string> { + return new Set(room?.getAccountData(ReadPinsEventId)?.getContent()?.event_ids ?? []); +} + +/** + * Get the read pinned event IDs from a room. + * @param room + */ +export const useReadPinnedEvents = (room?: Room): Set<string> => { + const [readPinnedEvents, setReadPinnedEvents] = useState<Set<string>>(new Set()); + + // Update the read pinned events when the room state changes + // Filter out events that are not read pinned events + const update = useCallback( + (ev?: MatrixEvent) => { + if (ev && ev.getType() !== ReadPinsEventId) return; + setReadPinnedEvents(getReadPinnedEventIds(room)); + }, + [room], + ); + + useTypedEventEmitter(room, RoomEvent.AccountData, update); + useEffect(() => { + setReadPinnedEvents(getReadPinnedEventIds(room)); + return () => { + setReadPinnedEvents(new Set()); + }; + }, [room]); + return readPinnedEvents; +}; + +/** + * Fetch the pinned event + * @param room + * @param pinnedEventId + * @param cli + */ +async function fetchPinnedEvent(room: Room, pinnedEventId: string, cli: MatrixClient): Promise<MatrixEvent | null> { + const timelineSet = room.getUnfilteredTimelineSet(); + // Get the event from the local timeline + const localEvent = timelineSet + ?.getTimelineForEvent(pinnedEventId) + ?.getEvents() + .find((e) => e.getId() === pinnedEventId); + + // Decrypt the event if it's encrypted + // Can happen when the tab is refreshed and the pinned events card is opened directly + if (localEvent?.isEncrypted()) { + await cli.decryptEventIfNeeded(localEvent); + } + + // If the event is available locally, return it if it's pinnable + // or if it's redacted (to show the redacted event and to be able to unpin it) + // Otherwise, return null + if (localEvent) return PinningUtils.isUnpinnable(localEvent) ? localEvent : null; + + try { + // The event is not available locally, so we fetch the event and latest edit in parallel + const [ + evJson, + { + events: [edit], + }, + ] = await Promise.all([ + cli.fetchRoomEvent(room.roomId, pinnedEventId), + cli.relations(room.roomId, pinnedEventId, RelationType.Replace, null, { limit: 1 }), + ]); + + const event = new MatrixEvent(evJson); + + // Decrypt the event if it's encrypted + if (event.isEncrypted()) { + await cli.decryptEventIfNeeded(event); + } + + // Handle poll events + await room.processPollEvents([event]); + + const senderUserId = event.getSender(); + if (senderUserId && PinningUtils.isUnpinnable(event)) { + // Inject sender information + event.sender = room.getMember(senderUserId); + // Also inject any edits we've found + if (edit) event.makeReplaced(edit); + + return event; + } + } catch (err) { + logger.error(`Error looking up pinned event ${pinnedEventId} in room ${room.roomId}`); + logger.error(err); + } + return null; +} + +/** + * Fetch the pinned events + * @param room + * @param pinnedEventIds + */ +export function useFetchedPinnedEvents(room: Room, pinnedEventIds: string[]): Array<MatrixEvent | null> | null { + const cli = useMatrixClientContext(); + + return useAsyncMemo( + () => + Promise.all( + pinnedEventIds.map( + async (eventId): Promise<MatrixEvent | null> => fetchPinnedEvent(room, eventId, cli), + ), + ), + [cli, room, pinnedEventIds], + null, + ); +} + +/** + * Fetch the pinned events and sort them by from the oldest to the newest + * The order is determined by the event timestamp + * @param room + * @param pinnedEventIds + */ +export function useSortedFetchedPinnedEvents(room: Room, pinnedEventIds: string[]): Array<MatrixEvent | null> { + const pinnedEvents = useFetchedPinnedEvents(room, pinnedEventIds); + return useMemo(() => { + if (!pinnedEvents) return []; + + return pinnedEvents.sort((a, b) => { + if (!a) return -1; + if (!b) return 1; + return a.getTs() - b.getTs(); + }); + }, [pinnedEvents]); +} diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index 889fc157e9..352ab43762 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -2048,6 +2048,13 @@ "not_found_title": "This room or space does not exist.", "not_found_title_name": "%(roomName)s does not exist.", "peek_join_prompt": "You're previewing %(roomName)s. Want to join it?", + "pinned_message_banner": { + "button_close_list": "Close list", + "button_view_all": "View all", + "description": "This room has pinned messages. Click to view them.", + "go_to_message": "View the pinned message in the timeline.", + "title": "<bold>%(index)s of %(length)s</bold> Pinned messages" + }, "read_topic": "Click to read topic", "rejecting": "Rejecting inviteā¦", "rejoin_button": "Re-join", diff --git a/src/utils/PinningUtils.ts b/src/utils/PinningUtils.ts index 22db64a6f1..9a20a721b9 100644 --- a/src/utils/PinningUtils.ts +++ b/src/utils/PinningUtils.ts @@ -37,11 +37,19 @@ export default class PinningUtils { * @return {boolean} True if the event may be pinned, false otherwise. */ public static isPinnable(event: MatrixEvent): boolean { - if (!event) return false; - if (!this.PINNABLE_EVENT_TYPES.includes(event.getType())) return false; if (event.isRedacted()) return false; + return PinningUtils.isUnpinnable(event); + } - return true; + /** + * Determines if the given event may be unpinned. + * @param {MatrixEvent} event The event to check. + * @return {boolean} True if the event may be unpinned, false otherwise. + */ + public static isUnpinnable(event: MatrixEvent): boolean { + if (!event) return false; + if (event.isRedacted()) return true; + return this.PINNABLE_EVENT_TYPES.includes(event.getType()); } /** diff --git a/test/components/views/right_panel/PinnedMessagesCard-test.tsx b/test/components/views/right_panel/PinnedMessagesCard-test.tsx index 64961ca144..cfa32fa490 100644 --- a/test/components/views/right_panel/PinnedMessagesCard-test.tsx +++ b/test/components/views/right_panel/PinnedMessagesCard-test.tsx @@ -20,7 +20,6 @@ import { mocked, MockedObject } from "jest-mock"; import { MatrixEvent, RoomStateEvent, - IEvent, Room, IMinimalEvent, EventType, @@ -266,9 +265,8 @@ describe("<PinnedMessagesCard />", () => { // Redacted messages are unpinnable const pin = mkEvent({ event: true, - type: EventType.RoomMessage, + type: EventType.RoomCreate, content: {}, - unsigned: { redacted_because: {} as unknown as IEvent }, room: "!room:example.org", user: "@alice:example.org", }); @@ -280,9 +278,8 @@ describe("<PinnedMessagesCard />", () => { // Redacted messages are unpinnable const pin = mkEvent({ event: true, - type: EventType.RoomMessage, + type: EventType.RoomCreate, content: {}, - unsigned: { redacted_because: {} as unknown as IEvent }, room: "!room:example.org", user: "@alice:example.org", }); diff --git a/test/components/views/rooms/PinnedMessageBanner-test.tsx b/test/components/views/rooms/PinnedMessageBanner-test.tsx new file mode 100644 index 0000000000..4df0127d82 --- /dev/null +++ b/test/components/views/rooms/PinnedMessageBanner-test.tsx @@ -0,0 +1,235 @@ +/* + * 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. + */ + +import { act, screen, render } from "@testing-library/react"; +import React from "react"; +import { EventType, IEvent, MatrixClient, MatrixEvent, Room } from "matrix-js-sdk/src/matrix"; +import userEvent from "@testing-library/user-event"; + +import * as pinnedEventHooks from "../../../../src/hooks/usePinnedEvents"; +import { PinnedMessageBanner } from "../../../../src/components/views/rooms/PinnedMessageBanner"; +import { RoomPermalinkCreator } from "../../../../src/utils/permalinks/Permalinks"; +import { stubClient } from "../../../test-utils"; +import dis from "../../../../src/dispatcher/dispatcher"; +import RightPanelStore from "../../../../src/stores/right-panel/RightPanelStore"; +import { RightPanelPhases } from "../../../../src/stores/right-panel/RightPanelStorePhases"; +import { UPDATE_EVENT } from "../../../../src/stores/AsyncStore"; +import { Action } from "../../../../src/dispatcher/actions"; + +describe("<PinnedMessageBanner />", () => { + const userId = "@alice:server.org"; + const roomId = "!room:server.org"; + + let mockClient: MatrixClient; + let room: Room; + let permalinkCreator: RoomPermalinkCreator; + beforeEach(() => { + mockClient = stubClient(); + room = new Room(roomId, mockClient, userId); + permalinkCreator = new RoomPermalinkCreator(room); + jest.spyOn(dis, "dispatch").mockReturnValue(undefined); + }); + + afterEach(() => { + jest.restoreAllMocks(); + }); + + /** + * Create a pinned event with the given content. + * @param content + */ + function makePinEvent(content?: Partial<IEvent>) { + return new MatrixEvent({ + type: EventType.RoomMessage, + sender: userId, + content: { + body: "First pinned message", + msgtype: "m.text", + }, + room_id: roomId, + origin_server_ts: 0, + event_id: "$eventId", + ...content, + }); + } + + const event1 = makePinEvent(); + const event2 = makePinEvent({ + event_id: "$eventId2", + content: { body: "Second pinned message" }, + }); + const event3 = makePinEvent({ + event_id: "$eventId3", + content: { body: "Third pinned message" }, + }); + const event4 = makePinEvent({ + event_id: "$eventId4", + content: { body: "Fourth pinned message" }, + }); + + /** + * Render the banner + */ + function renderBanner() { + return render(<PinnedMessageBanner permalinkCreator={permalinkCreator} room={room} />); + } + + it("should render nothing when there are no pinned events", async () => { + jest.spyOn(pinnedEventHooks, "usePinnedEvents").mockReturnValue([]); + jest.spyOn(pinnedEventHooks, "useSortedFetchedPinnedEvents").mockReturnValue([]); + const { container } = renderBanner(); + expect(container).toBeEmptyDOMElement(); + }); + + it("should render a single pinned event", async () => { + jest.spyOn(pinnedEventHooks, "usePinnedEvents").mockReturnValue([event1.getId()!]); + jest.spyOn(pinnedEventHooks, "useSortedFetchedPinnedEvents").mockReturnValue([event1]); + + const { asFragment } = renderBanner(); + + expect(screen.getByText("First pinned message")).toBeVisible(); + expect(screen.queryByRole("button", { name: "View all" })).toBeNull(); + expect(asFragment()).toMatchSnapshot(); + }); + + it("should render 2 pinned event", async () => { + jest.spyOn(pinnedEventHooks, "usePinnedEvents").mockReturnValue([event1.getId()!, event2.getId()!]); + jest.spyOn(pinnedEventHooks, "useSortedFetchedPinnedEvents").mockReturnValue([event1, event2]); + + const { asFragment } = renderBanner(); + + expect(screen.getByText("Second pinned message")).toBeVisible(); + expect(screen.getByTestId("banner-counter")).toHaveTextContent("2 of 2 Pinned messages"); + expect(screen.getAllByTestId("banner-indicator")).toHaveLength(2); + expect(screen.queryByRole("button", { name: "View all" })).toBeVisible(); + expect(asFragment()).toMatchSnapshot(); + }); + + it("should render 4 pinned event", async () => { + jest.spyOn(pinnedEventHooks, "usePinnedEvents").mockReturnValue([ + event1.getId()!, + event2.getId()!, + event3.getId()!, + event4.getId()!, + ]); + jest.spyOn(pinnedEventHooks, "useSortedFetchedPinnedEvents").mockReturnValue([event1, event2, event3, event4]); + + const { asFragment } = renderBanner(); + + expect(screen.getByText("Fourth pinned message")).toBeVisible(); + expect(screen.getByTestId("banner-counter")).toHaveTextContent("4 of 4 Pinned messages"); + expect(screen.getAllByTestId("banner-indicator")).toHaveLength(3); + expect(screen.queryByRole("button", { name: "View all" })).toBeVisible(); + expect(asFragment()).toMatchSnapshot(); + }); + + it("should rotate the pinned events when the banner is clicked", async () => { + jest.spyOn(pinnedEventHooks, "usePinnedEvents").mockReturnValue([event1.getId()!, event2.getId()!]); + jest.spyOn(pinnedEventHooks, "useSortedFetchedPinnedEvents").mockReturnValue([event1, event2]); + + renderBanner(); + expect(screen.getByText("Second pinned message")).toBeVisible(); + + await userEvent.click(screen.getByRole("button", { name: "View the pinned message in the timeline." })); + expect(screen.getByText("First pinned message")).toBeVisible(); + expect(screen.getByTestId("banner-counter")).toHaveTextContent("1 of 2 Pinned messages"); + expect(dis.dispatch).toHaveBeenCalledWith({ + action: Action.ViewRoom, + event_id: event2.getId(), + highlighted: true, + room_id: room.roomId, + metricsTrigger: undefined, // room doesn't change + }); + + await userEvent.click(screen.getByRole("button", { name: "View the pinned message in the timeline." })); + expect(screen.getByText("Second pinned message")).toBeVisible(); + expect(screen.getByTestId("banner-counter")).toHaveTextContent("2 of 2 Pinned messages"); + expect(dis.dispatch).toHaveBeenCalledWith({ + action: Action.ViewRoom, + event_id: event1.getId(), + highlighted: true, + room_id: room.roomId, + metricsTrigger: undefined, // room doesn't change + }); + }); + + describe("Right button", () => { + beforeEach(() => { + jest.spyOn(pinnedEventHooks, "usePinnedEvents").mockReturnValue([event1.getId()!, event2.getId()!]); + jest.spyOn(pinnedEventHooks, "useSortedFetchedPinnedEvents").mockReturnValue([event1, event2]); + }); + + it("should display View all button if the right panel is closed", async () => { + // The Right panel is closed + jest.spyOn(RightPanelStore.instance, "isOpenForRoom").mockReturnValue(false); + + renderBanner(); + expect(screen.getByRole("button", { name: "View all" })).toBeVisible(); + }); + + it("should display View all button if the right panel is not opened on the pinned message list", async () => { + // The Right panel is opened on another card + jest.spyOn(RightPanelStore.instance, "isOpenForRoom").mockReturnValue(true); + jest.spyOn(RightPanelStore.instance, "currentCard", "get").mockReturnValue({ + phase: RightPanelPhases.RoomMemberList, + }); + + renderBanner(); + expect(screen.getByRole("button", { name: "View all" })).toBeVisible(); + }); + + it("should display Close list button if the message pinning list is displayed", async () => { + // The Right panel is closed + jest.spyOn(RightPanelStore.instance, "isOpenForRoom").mockReturnValue(true); + jest.spyOn(RightPanelStore.instance, "currentCard", "get").mockReturnValue({ + phase: RightPanelPhases.PinnedMessages, + }); + + renderBanner(); + expect(screen.getByRole("button", { name: "Close list" })).toBeVisible(); + }); + + it("should open or close the message pinning list", async () => { + // The Right panel is closed + jest.spyOn(RightPanelStore.instance, "isOpenForRoom").mockReturnValue(true); + jest.spyOn(RightPanelStore.instance, "currentCard", "get").mockReturnValue({ + phase: RightPanelPhases.PinnedMessages, + }); + jest.spyOn(RightPanelStore.instance, "showOrHidePhase").mockReturnValue(); + + renderBanner(); + await userEvent.click(screen.getByRole("button", { name: "Close list" })); + expect(RightPanelStore.instance.showOrHidePhase).toHaveBeenCalledWith(RightPanelPhases.PinnedMessages); + }); + + it("should listen to the right panel", async () => { + // The Right panel is closed + jest.spyOn(RightPanelStore.instance, "isOpenForRoom").mockReturnValue(true); + jest.spyOn(RightPanelStore.instance, "currentCard", "get").mockReturnValue({ + phase: RightPanelPhases.PinnedMessages, + }); + + renderBanner(); + expect(screen.getByRole("button", { name: "Close list" })).toBeVisible(); + + jest.spyOn(RightPanelStore.instance, "isOpenForRoom").mockReturnValue(false); + act(() => { + RightPanelStore.instance.emit(UPDATE_EVENT); + }); + expect(screen.getByRole("button", { name: "View all" })).toBeVisible(); + }); + }); +}); diff --git a/test/components/views/rooms/__snapshots__/PinnedMessageBanner-test.tsx.snap b/test/components/views/rooms/__snapshots__/PinnedMessageBanner-test.tsx.snap new file mode 100644 index 0000000000..fa4c793d90 --- /dev/null +++ b/test/components/views/rooms/__snapshots__/PinnedMessageBanner-test.tsx.snap @@ -0,0 +1,166 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[`<PinnedMessageBanner /> should render 2 pinned event 1`] = ` +<DocumentFragment> + <div + aria-label="This room has pinned messages. Click to view them." + class="mx_PinnedMessageBanner" + data-single-message="false" + data-testid="pinned-message-banner" + > + <button + aria-label="View the pinned message in the timeline." + class="mx_PinnedMessageBanner_main" + type="button" + > + <div + class="mx_PinnedMessageBanner_content" + > + <div + class="mx_PinnedMessageBanner_Indicators" + > + <div + class="mx_PinnedMessageBanner_Indicator" + data-testid="banner-indicator" + /> + <div + class="mx_PinnedMessageBanner_Indicator mx_PinnedMessageBanner_Indicator--active" + data-testid="banner-indicator" + /> + </div> + <div + class="mx_PinnedMessageBanner_PinIcon" + width="20" + /> + <div + class="mx_PinnedMessageBanner_title" + data-testid="banner-counter" + > + <span> + <span + class="mx_PinnedMessageBanner_title_counter" + > + 2 of 2 + </span> + Pinned messages + </span> + </div> + <span + class="mx_PinnedMessageBanner_message" + > + Second pinned message + </span> + </div> + </button> + <button + class="_button_zt6rp_17 mx_PinnedMessageBanner_actions" + data-kind="tertiary" + data-size="lg" + role="button" + tabindex="0" + > + View all + </button> + </div> +</DocumentFragment> +`; + +exports[`<PinnedMessageBanner /> should render 4 pinned event 1`] = ` +<DocumentFragment> + <div + aria-label="This room has pinned messages. Click to view them." + class="mx_PinnedMessageBanner" + data-single-message="false" + data-testid="pinned-message-banner" + > + <button + aria-label="View the pinned message in the timeline." + class="mx_PinnedMessageBanner_main" + type="button" + > + <div + class="mx_PinnedMessageBanner_content" + > + <div + class="mx_PinnedMessageBanner_Indicators" + > + <div + class="mx_PinnedMessageBanner_Indicator mx_PinnedMessageBanner_Indicator--active" + data-testid="banner-indicator" + /> + <div + class="mx_PinnedMessageBanner_Indicator mx_PinnedMessageBanner_Indicator--hidden" + data-testid="banner-indicator" + /> + <div + class="mx_PinnedMessageBanner_Indicator mx_PinnedMessageBanner_Indicator--hidden" + data-testid="banner-indicator" + /> + </div> + <div + class="mx_PinnedMessageBanner_PinIcon" + width="20" + /> + <div + class="mx_PinnedMessageBanner_title" + data-testid="banner-counter" + > + <span> + <span + class="mx_PinnedMessageBanner_title_counter" + > + 4 of 4 + </span> + Pinned messages + </span> + </div> + <span + class="mx_PinnedMessageBanner_message" + > + Fourth pinned message + </span> + </div> + </button> + <button + class="_button_zt6rp_17 mx_PinnedMessageBanner_actions" + data-kind="tertiary" + data-size="lg" + role="button" + tabindex="0" + > + View all + </button> + </div> +</DocumentFragment> +`; + +exports[`<PinnedMessageBanner /> should render a single pinned event 1`] = ` +<DocumentFragment> + <div + aria-label="This room has pinned messages. Click to view them." + class="mx_PinnedMessageBanner" + data-single-message="true" + data-testid="pinned-message-banner" + > + <button + aria-label="View the pinned message in the timeline." + class="mx_PinnedMessageBanner_main" + type="button" + > + <div + class="mx_PinnedMessageBanner_content" + > + <div + class="mx_PinnedMessageBanner_PinIcon" + width="20" + /> + <span + class="mx_PinnedMessageBanner_message" + > + First pinned message + </span> + </div> + </button> + </div> +</DocumentFragment> +`; diff --git a/test/utils/PinningUtils-test.ts b/test/utils/PinningUtils-test.ts index 47434c4fca..adfd268bf1 100644 --- a/test/utils/PinningUtils-test.ts +++ b/test/utils/PinningUtils-test.ts @@ -73,15 +73,27 @@ describe("PinningUtils", () => { ).mockReturnValue(true); }); - describe("isPinnable", () => { + describe("isUnpinnable", () => { test.each(PinningUtils.PINNABLE_EVENT_TYPES)("should return true for pinnable event types", (eventType) => { const event = makePinEvent({ type: eventType }); - expect(PinningUtils.isPinnable(event)).toBe(true); + expect(PinningUtils.isUnpinnable(event)).toBe(true); }); test("should return false for a non pinnable event type", () => { const event = makePinEvent({ type: EventType.RoomCreate }); - expect(PinningUtils.isPinnable(event)).toBe(false); + expect(PinningUtils.isUnpinnable(event)).toBe(false); + }); + + test("should return true for a redacted event", () => { + const event = makePinEvent({ unsigned: { redacted_because: "because" as unknown as IEvent } }); + expect(PinningUtils.isUnpinnable(event)).toBe(true); + }); + }); + + describe("isPinnable", () => { + test.each(PinningUtils.PINNABLE_EVENT_TYPES)("should return true for pinnable event types", (eventType) => { + const event = makePinEvent({ type: eventType }); + expect(PinningUtils.isPinnable(event)).toBe(true); }); test("should return false for a redacted event", () => { -- GitLab