From b55653ddf0a8ee59d34b365c5d41df3b85e30535 Mon Sep 17 00:00:00 2001 From: Michael Telatynski <7t3chguy@gmail.com> Date: Wed, 31 Jul 2024 10:38:25 +0100 Subject: [PATCH] Extract Extensions into their own right panel tab (#12844) * Extract useIsVideoRoom hook Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Move useWidgets hook to WidgetUtils Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Extract Extensions into their own right panel tab Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Remove unused components & classes Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Tests Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> * Update screenshots Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --------- Signed-off-by: Michael Telatynski <7t3chguy@gmail.com> --- playwright/e2e/integration-manager/utils.ts | 6 +- .../e2e/right-panel/right-panel.spec.ts | 3 +- ...omSummaryCard-with-verified-e2ee-linux.png | Bin 25768 -> 26253 bytes .../with-name-and-address-linux.png | Bin 30147 -> 30603 bytes res/css/_components.pcss | 1 + res/css/views/right_panel/_BaseCard.pcss | 44 ---- .../views/right_panel/_ExtensionsCard.pcss | 145 ++++++++++++ .../views/right_panel/_RoomSummaryCard.pcss | 143 ------------ .../css/_light-high-contrast.pcss | 8 - src/components/structures/RightPanel.tsx | 9 +- src/components/views/right_panel/BaseCard.tsx | 17 +- .../views/right_panel/ExtensionsCard.tsx | 214 ++++++++++++++++++ .../views/right_panel/RightPanelTabs.tsx | 31 ++- .../views/right_panel/RoomSummaryCard.tsx | 207 +---------------- .../views/right_panel/WidgetCard.tsx | 3 +- .../views/rooms/LegacyRoomHeader.tsx | 2 +- src/hooks/room/useRoomCall.ts | 2 +- src/i18n/strings/en_EN.json | 8 +- .../right-panel/RightPanelStorePhases.ts | 1 + src/utils/WidgetUtils.ts | 24 +- .../views/right_panel/ExtensionsCard-test.tsx | 159 +++++++++++++ .../views/right_panel/RightPanelTabs-test.tsx | 4 +- .../ExtensionsCard-test.tsx.snap | 194 ++++++++++++++++ .../RightPanelTabs-test.tsx.snap | 28 +++ .../RoomSummaryCard-test.tsx.snap | 42 ---- 25 files changed, 820 insertions(+), 475 deletions(-) create mode 100644 res/css/views/right_panel/_ExtensionsCard.pcss create mode 100644 src/components/views/right_panel/ExtensionsCard.tsx create mode 100644 test/components/views/right_panel/ExtensionsCard-test.tsx create mode 100644 test/components/views/right_panel/__snapshots__/ExtensionsCard-test.tsx.snap diff --git a/playwright/e2e/integration-manager/utils.ts b/playwright/e2e/integration-manager/utils.ts index c6a2fb998ee..0ea59e6ff73 100644 --- a/playwright/e2e/integration-manager/utils.ts +++ b/playwright/e2e/integration-manager/utils.ts @@ -19,8 +19,6 @@ import type { ElementAppPage } from "../../pages/ElementAppPage"; export async function openIntegrationManager(app: ElementAppPage) { const { page } = app; await app.toggleRoomInfoPanel(); - await page - .locator(".mx_RoomSummaryCard_appsGroup") - .getByRole("button", { name: "Add widgets, bridges & bots" }) - .click(); + await page.getByRole("tab", { name: "Extensions" }).click(); + await page.getByRole("button", { name: "Add extensions" }).click(); } diff --git a/playwright/e2e/right-panel/right-panel.spec.ts b/playwright/e2e/right-panel/right-panel.spec.ts index f282d83d62c..f7b29585096 100644 --- a/playwright/e2e/right-panel/right-panel.spec.ts +++ b/playwright/e2e/right-panel/right-panel.spec.ts @@ -73,7 +73,8 @@ test.describe("RightPanel", () => { test("should handle clicking add widgets", async ({ page, app }) => { await viewRoomSummaryByName(page, app, ROOM_NAME); - await page.getByRole("button", { name: "Add widgets, bridges & bots" }).click(); + await page.getByRole("tab", { name: "Extensions" }).click(); + await page.getByRole("button", { name: "Add extensions" }).click(); await expect(page.locator(".mx_IntegrationManager")).toBeVisible(); }); diff --git a/playwright/snapshots/crypto/crypto.spec.ts/RoomSummaryCard-with-verified-e2ee-linux.png b/playwright/snapshots/crypto/crypto.spec.ts/RoomSummaryCard-with-verified-e2ee-linux.png index 2c6160f2a19014674bb21d2a27968750d282a2e6..d7c90ce5fe3b2c4fd1982a50f61f907a8662423a 100644 GIT binary patch literal 26253 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 literal 25768 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

^$@ z1;mwR@Mq}-k6{j%V%lUdAsnT0Ng|30)V_m3W~Uegb} z3j`ju5M}0e;sbqP0`GZN3|H%}a^=kj{^!o`Blt}+aS|D=HL+tN-g7HVj3J?X%Cmf@dJer}s40@6CGmcEkOQ#bcwyzmcn__a5ibTsg2wp&_I#>m#sxxwp?51^ZaI4!?ZjN-$nXzfcL} zb58yZiy~FMrt&jcN)J5zuSRono~&R~v&jG*BZSGNTpzy?z$97#x}ZyS!v7`fr$!oN z3@JZrJmb&=?1&GL=1fjZ4k1_YUjsw4>Gpb#R{F1jC1oc+U3Cw-SrR?)6Ofi%UF8n$ z6|fe>Zv!rIT1!a7rZcs4pVqX||JpZ^8x5Kj2aM91^=J75O9&u)?cZ%AL{)}ufRVES z3iV>UlY9@a+z1mDSZl_!kU(G7FTgv3*plmR8zu0WiOvODgKGN|+avl-wgzW*Z~*rt z!k%X@+?G~?yiuUM*Rl}9Tu7+$U*8mEv}b*H+pXzmyrf1NO1(S*77n;6$wz%?Q`z`v zJxa~da(vazFnLw6d66Wlf9FDjhRo0PGp2@9rKeab#N*v5!c7UrCLyq@yQTBB`_O9f zK=MMbj8`mYTxNtPOSmg@v$^|PvDwYPhMUwI^b-O1O8YvE)3T}q<7(^VnEGT;X=*Pp z5yNXfF-yBraf&@SHQEI5i%~N=Q%70G@B192Pwkmv zRTenOI(_Q(wPt8PL^A?bfzOrLK>ts`a{vNfS*uGdsWxg&m&*&4Zmnsx>8sWCiIDM& zZ@d3u0W?tuYpvno_LgNS8MpE^Wgf*Y4mX@Bxt;k1JH`kg84L8t8YvZ!- zV>!3MUxRV~=dG9P&dq=s7QH3`HTCpqiy0WKWcIEPXUGFQb-8nQAO?=LvC8v%DC z%&;}h;T)QT1a*Ue^QHLrw;V)vUo%fSpDv9Zm9kFT1qB5|Fv#08eyHiF%r8xd6;AZV zkT(LbiC5=4-=wLLOW)R52VG!LsOjm|07HzAkLxbXA0FCrml?D=b@TCF=MJ4D_=3&vsHoiSRBs3$-5TkL-^AkEzgzKs4tz#}hg%!;*&{@@ z*f8+fD1WaAtL|!OXqd1VUXqt@b>3@hZceUy9O!F$?nym4^%Q_$r9wNBeGfDSj#z|N z>aDk&AxdUuQ?LXZYisMEOMX5+;C2-FI6IU1-t|k3S11s+xBA^5C)zDkx4I%_kB`@2 z3OzKHmyR zsuNhEu6&RCTjy6-jAQtg96BPO18yeiXlU}^Zz!JM`a)s>MNNh3H@H@pmdYv&2LhM_ z!-Ph=rH3`d8v}cpo89S&33hIF-3Ht0hK8$Vm!0!W{I?KV+=0td0FIp4t@nyOEx*(v*optsd<9 zAm;?tL3X-aACl#4lRxDjFP@FZqU7k$HH&E`QTlpq>%ldg!lIAn=K~B(+pFwQ8yxpw z2^36a291(UBzU~?O#&XnwrkFtbx5|^?WE7RIyKPLX=0-BYBQiP+o|vULbtZXK)AIH4JnOQhm3>-!lb65f!_Hl3QUTGhbLrX`YXq*%OTHBdl=`X zSQV_G!2D27rElo)q|}B!fnJY`jSZK1;=*zk&Rvw5=^5EShvntV47aNM`~>Kl?OYqS z&+RRN0U|=slTB}F=h0GTdOFoYOR$pkNlA%KRZ!MX&=@T2$-kRnuz}pn|0MRMAy2-& zepJ>Oa6{GpQkRvB>opUBA6*$0wRZ?1#pL`n*LpZm6x)hWv+lwai3|%Xc5KegHQ5Mu zTM4+YFE2-T$K+gl2vYR$6AD;U5q@6vyARL|p=zqF#nEN`a4RMCLoUrnx8_JHc?HnM zHwus3l{Hom+_-4LPO7TxqD8f}vUP2_xvF*1o05@09V%6~>Re71)n$>-l@I)p0%vM` ze*f^0+IMbokx{Q_cqEBYyUw&fr|?yfw)UK2#-_#M2qQByP))nPi3bY`E>*U-sETgn zIyw>)64o~~P(o64b;S7rf5_HWBXF-w(fiX8X1n}BWJ5KuGy>IK3)sy2+dHH|_G1fU zRK`ToAj-Xx*A$!UhmrXRER{~|CMMrW*pvwglXDb5Ao-Zu+e=PO{YeDwXaoco1qBzY zlMn-hFV>_o-$J5EBXG!C=jZ1G0|T|3vHiuA)xqV5H`?wETGoAiO~QMXEq4fL1p4nwT#QCQdX2aUK*6W8zrjbl;i{FylkLo)M4gtGI zM|g?C{tu?chJ9tcsLTF4f;7K{zKVs!xVj4Pqno?%bUw8Z=w^Hns&4J7G46N z?zQB2&S;^qi_^CqULow9oKrJ1y+S65~;HBESZEPcFjx)TlfpN$am>rjn%@%;t?m$xu8SuD}HIo<;EB=pws}9$#&+$(B@#CWFid3wF^u}uhljX?M>?R!P zSZeX@mKO{2dMZI9G}Hg-@|>juzvItr->$O$Rp_iEQ*@aqTb2$KfIa=9yi0wCP zG+CzAaj_#P97((*ldU8tCzq2;rPxc}3xgB2To-@lr;~ALzYVU8X)G=d1EPI#aerOt z=}G6~-Qgb3+Ls8dnz|~Ufa8m_Id*jPJq{vhz}FQZoH1+HSmL&@`gyB$&E06To5;z_ z)8d9F&D;R@qZ#kFFZBPTj<{#ghyw$bcF&v9FQ>(-Lql?OxZ&AxMq(zpXhub`I+>gT znUi)!uTOo6P%QwEYS4d=vj4(YL(BzcPW8r`);|CI0sptb|0fiy=cdfw?n-iQ{3kni*a!qV3h;kGR#OJXVOdc_e5+#qoZ>nJ#85Gp)sIj}oZexOmzL&#pGnh<7L`2N( z;J;?HoJ+95qq(`bC?J$wg=B)T>$W}E5DIkT3~9KGX{4=RfXrcSeT$bDvnshvqe834lnrp! z@%Hab@R-wt*?)~_HWcR+tL^^|d%|8*rKhKl$>a&U~XVhisAiUm$BdRgzX3)3C|mJpzW;g>Zc=_!*Cn&&RP@uPnAt zZR~gB%d-yYS-szy@4Zq7S>0~_4k>7|&$YQ3D-%Gn=s|S`s}w%L*GJQRc0;DeLYmic z+AjZYq+v;DKArf*k!hj9{&l`S`tM&MAtg_G*?LA=Adtg(rqw&_6a+Q$s@o431B|SGq9}AR88s zVH-kW;;ZGdN1Gj*cP5kTlKBAl%sWxn+&mXT-o~IK>R4hq*1uFH@gx+aEpl;np9m!u zzBx6qE!h=*;(3jWySuT0$2u0!1ux8YJNF*t>`0`I<#pt+c`xTWp!g#{KA{8gZN>Ng z@k?OH-Q67|NFy^7L45-fOYh)vDXur3K;DAc%Q|Db^7b=$?NXnVs` z0Hak|T>PgXT!AOxMXM^1jU{n8=qSF6|7VeLhOS)v%+M6DBt?&!^$o1l!T;8c#eK(i zsfF|7#}~);6~JPthQHF3k0opC^1N_0QH|e~n|N&<4f}UbvL>NID5@bgi60V(hSLN? zm>w=BFxONI4F~Pug{<>9`Pgk*TUv|*6bK2g--pP(PUPlpJX{FC;wN6I@ybOh41d=_ z8hR}OCt>HVE>Bva-7{$?z2;TFD_HV~=uhyBK`6sn+c0$gj^&3ifi92ZD&`pX)7?Tx zX29*yj)DIm6x#hsjZ>ZDKT_i&IGd7L-X2KhdoYKU|I8ZwnWc2-V_+mBvTBM?kwgbK8b$!OX1@Y8!&XX(YT-0qng)3YurshF)T z!TsIC$YfrJsR1*&cjx-vlE%ibHH^-;(MQ&m$Nm+>f0VPrdP|=4XgCLJA}*T%M;7&DRZ!|IZv&?8F&<6US(TCFHfnl^DDzk@Sys!a{y7PUM| zQO|t7R$U~Unwqj(eCUb|VXICJ&Gda(3%;}oqH$Kh6KqRc{de3S<|#M()EtyMlWVWx z5rU?X=szJL_0k_EsM|6=DJq4yYlV-+Nv&&3BU}qvHvb~ zD=AZ3M@vgb%lCH6qU$w-tZe^(#B7-e97<)A%0-dD&EHp#1Ys|QL6HR?+@`a%$%Kb{ z6>i$wdVrcc=x_0q&CAORDSNl5Z|BsBDC-F*i^*xY562oRIe_g2g9W*!6LTD5ggy2`GBKCsWFn%Gh@F0TQ3hA$m$vR~CPzqZ45zhv zGEuQ7b#L+URrQrTDbpQK$JTB;igQ)&`jgiTI?|Oy4{eeX*VMF3FApP7sDV`rWwW(( zqy+~*i@Y7(HK5_=n}udz&yAQ9;3j0WdX_iU`R+sz<4sYm_1r%8^@qg3c7`GwYFJsA z89Kc;@I5}a8lMS3Mhn~q(b3T$4$YpN{WCs#Sn<4de8{!UcvJuKgEu#T3f#lHFD_ zKbCRXRWRlH@{!_;(Pe#oy^AwBfD7Ip0U$u5^W{?-=maYn01jLv$-zz!>hF^Fdvb5+~|mOYxPn_qD&tP6fK?5n_T^kUI#kMre+uFTk+J!pGOu+wma z`ZR@qTN_QtJhVVp1EVCi02_+FhtRu@19*?9dxi+q{6%?gfN)c;C-*KMDkt}J56zgo zD9cARr-G!V9}++#@TTQH$<#O0XmwaJi-!KGxm}%j&d;|n!Am329>X>g5E7=Nnd<+7 zhs_n%yFrtmXDs#85zSqVH-4XNJN8cWBr`NszRd?TMzc?SQeGHm`tcOSCr9nKuVV`NuX^E~VH|f!l z`S6cmK>c|-^UB~#S?m?VBHjaYo`f_zLD^o1Z5~=?CdBs=Z?4&+1ELghosphxBTU8| zl1m2oAn)R&8@Lk51D@KO5S%bI$57ZvT43>loQD8xy))|##l`Y_10$NV9p-vBSHlHx zQF;5s(iAfPr?RpkY|*2m5p!K)XVb<8w^Pryq?HFHt?}_Y+Xg%^7z~NUPi9Q>2Y6Sg z6u);+9ZlG|eYkj{@|y`o0bDd9#YI=o)DE-${c+)=Z^zI6xOz+bvWWP=O`%V%%hAKk z5UlhHmgWsMTauSA9|4C^p~Kf%&>(d1EBAogp|Rer?Q!0{|BMP!L$(P(A(opxo`>7- zwPfZWZH=sB7e6BVm?H6kJ8Nro_0V3o$mEVe;?OW)Rc1~;pY#Omj!4Puhi4OnEt;YK~8>f?u=dN>Px%cS}4++Lq&oFbE6+vkCFmZdY7uF%q zS(MAFBT2kboufVD;Bc^+g{p?Kwl-LnIZN0mb`zVkG z<&O1uH4zaLV-(|);V;fl``_H`0SII%g)|_6OCb@!Zv17XD!RW<>_Wcd;p&!eA$W6D z_^8eaiGEts(OJMG7fz2$@Y$WEJ49If`Eyk&Gobb0V9Dybw$x^yhomB7xpstspSU#V z8_Y(Au5cJ!QEV6M4hAnRdBtP`_VeI>v6*nt4-jGWHx`lI({6g!&OCt(A^lTRTKxUZ z;vbto`FQ#n$4#7of1)q7uEMO|PMjWxeIjSURP-P?T$vm-gp9V|^NP2;Gl~hVctyeC zVO|$U@d!9xeVMj|%eN?tAChjdP7;&RDALGbB*EFNHP0Q9nl zi{`=E=8;pLuMLO3`v4;aC=;fprZA=vGYF*8j61CpTO18Y1P3E%^LlZss-W*(061tM zZhz5r+4^>ShMcsn07lB-dBHDPtrk?>P-n;%Il=CNKTPVyr;Y3*?#hH49t}vXo!daj z<7_@k*W>=~PG0^^#5Obyn^$5U5F0Hn=|6V&*PW6*PpA7N^LpWL7c4ZE)w8nyiHi4( z2_?b%#(mPJJ@#np4hZex>$=3baZGO}!Hn5rcS0Y6a>)lC+p^sm1yB)hy`bLON2`Cy zxF)Ax;XrSNd2Ie)DZ8*}81*k8C%m{M<2J=YU9TGB6!&||Y?S|jHdfdhT(#V0maCk^_@n+LW9#iyO{KH)7uvudj*@9fpvQVJ3B`SpIkM(h9RN_h z`i;;CyJfpVt=1)9Pzf0m{Q9z-7jEz!@}g6cBwj&J;J45FPs7T$jv-uBLWfIOO(9ru z-7$tMX0zf=6f&G?X=s;HA#lS)ztKB6;g6LJ07lynRzhM87MeKe* z)ARe?9{O=uJ+U9!s3U*8v&Us!r*g+8*_AK3k&t$1@y|uRU<<8rid6+Hw%X_2W98S5PvB|3=Rz)1B zdSdtoex$wh|EKHVx_2W*zD;7OGMr?Kp`j%H@b}CWDGy@sM8t$Zssy|7WsKLDne3lC zPzFZ8`e3H=FelqdF1RPSOa&zJuyFd5YyI~(%OU|Q0Kk@v*S`lkwFj7+*b@PhijT9QRsupR{Tb@&s=9hQYbOUm>Zx2b)K81~i@mo11@&vrIFJ}$ zmg4JbrywHAHF$5Jvn; z4i*Y#L%ZNIerU>#?B`ugYVr(?k$U%E<&L)&Xo{nvcKoXlP1bB^*gU2@&4kLTmlu{m z-i|@apP!q1bZFV>cTO}G=Myq1g`_?+P0sst*in#7#||8QJq!&U9kD1lcz8mWrnb*- z0Mio6WI3OX7rETvtn+YXi;Th&eYCw|aCm$_y5a#aV(B9hX~X#h8ef_g{FcfHqdNoV@p4kZlIV5b zsrk9wykx@{KufpFn*2L^nAJxkYaMSpyLPrfZ~fETugo`W(pGOd`xM?{xn4&*{?XN( ziS-x8(d_{66Z@BW`|~YSy$aNYi-ZYpdYg`y{a^Uf-YQhN`Y_+Og#~AqahlYmCYk8X-=;#<0E^lXEy^;|7)Z#-8ZU#!tg^My<&Qr%Q z-G-l`u7vl)Ke|c3vxs~Kux*Fl_h-)y5+C05986aX40y%*9$Ymr9RL_&EKv@kD9Kzv z^s=5Ce;8(3T3W&oC#J{zckGFz&{YG!y`-uk_>8vNj4OBrSpDzaKBUBS(&N^mmKJ0J=5p=&w2P6DXYc#F3a}zQ9UVY@x`M$X zQ}8SPayj_0J%}hSx{nR8L{FaY<;NPU?g2xl#v@3gWb3zhxUs?pKr3~!0|N@b)Aj2N z?FWupNx@41^}G7R1W@CDDha49$`k*&pMoT%4*R&{Lb`6Lj)blDVu?XAA8tf*MiF|KK99Lm7c z)m(ApX7ZE1-DBTLO-a?P)akJNwI~&H?yxBLYhY(MBMfW4&i^PnsR7+@u=(8W5}hHD zMZ3n)U)f1U#X0=669&r|O6B)iD!~&Fde-X->O7d4VglDWZo%^F-7bL(SETHc{e4b` zB*a$=7cdg;K4L~X1}P+T4A>{x!L~MmYVHDyMFUok;cpVCDB}6uQosrQ8(W0D^Z_u?!@@qy;h$3=rb+xmz>kk3CoBsI1 zrY~U;h0Xc-)zu&P*t&Y=2l~e-c;0^AZ3r@`q(jtG>I)U81h|-l(Sv1&h)CJ>|EssJ z0E(;KwroNO1VRGAg1cL=;2zwAyIXK~4Fn4o+}(o*3r=u%cXxN4FaQ7EyRYWmnVOk; zce+lU0{V2*{mGWK*51cV8IRpo!&Zt{`>5hHxN?hLSXi=E98{qp2}r(xb~827Yr}oF zT*j`DIK6~w@90467uJ>1rUiff3@>fSi1%(VT-f8Xw*0ja>>ryvJ+Tmq#Hhsaf4@oPPiNk8w1*Lr)i*m%hvYZMVlz~bP5 zj7-u`Rze+HNJJ#AkU9hAmk*SHN$Y)GE*V*yfTm`-RmK>&u-L*vk_?&k8@>* z<<;L!?1^o}#0Zg+uE>)i^nscw%vUci9dQ}J5O%fj;S-Jn)r>=Nqv9yHnw**e+nFM~ zC}PD}j>((LzVBFN`viPo9kYKg8p$7rIWxk4JbQjQ+U{p+Y@8IGoLQO&BEL~4Mi2Lf zvb$&nO)7!>?4RQ!t^DVSZQ!DzioX8dpjT<)M3INN3&duTaWu*FmZ4;lx!iqplso94 ze4seT?xa^Sn9fiXmnw93f7_br=0noJ<@xoU=gNS3jRWN`96EB^wWcX&nfaFX4t=A~ zdZwn4_Dn)D+Gztu#+yiuQ+y*n`YMzJYrSC~_N|0*-nOyt3=Dc&pDDp>U3isMRwDjc ziy9RsO$h}%Bl_e3++99kq5G`%TnVgITn?Af;^^@Q*w=`!?$>f3R{hUjonM4^b>MS5 z`gW~JA*2zxgoa=Y)|4@a^Ew<3t=WKOO4#c2d+!_m(aiYx{{A*!*24pWsJ7J+)7D@b zhsWT;grVy>vke$uO-bw* zlRSBuc8q!>wk}0U-YUj%kkXJ)SZ9vvDa2leg{67U)PPyANyVE+5hq`jKDwU@`TF%- zF06ghm;b97JgIjS!%Sq4fkz@;q=+RM42(2<+s(d()zNnJW*r%eoThwI%mW|L^-XjL zRYh)(*%Q)Jyv%-4_ipUsb{Z!kZPobwH_TW1FkRUO(9qCbYpcL3U<{^ZWsUB+zkP{` zy<70!yBv{@Vtrz2$kb=au*kQd+y_r;w1$Zf&zg~po;$IG0hgyOj2L{J`ch69gLue7@ihZVN?pCEI15%dT8WA=$Ux7WFRKkBRvfl~U-vv8wGak+ zGeZ_HK0uEdyq<(HsQvvoYvx|-z9KwSrE&of_;(OTiQY16den-&V8)#P`v1MyowAA15kUj*QwFcn3-AJCl+qwhtiOcizZ@rfg@#h8nQOSXvbw(HBK=+s4 z;=LCn)^_Uj_`ok?WhFh?2-Z8$avHVU67p)NweQ6NZJ*7`nuR)R^W9!iV`6RGgMq3B3$zP>?~k|4;Q608;ziq7MGU5l2uYw^=|~C3R@d&`V9BLic?!% z4_NZ6;9&6|_ig?XBV)#TXy*ILyMM^($dU3VXX2!T?R`QGIo>2qW$n`Y1E^?(&4%%J zQz%h@+K2WPD31dSEf9JDvb4C^!kuSna`FXrO_f_UL5W84UHX({oV`8l zGDBKgTA)nObx`34YPAxI#Muren6 zxn52+sL{ZV?E(=oc#l;UQ4}#TqbY-M&C}@PwSul#|F>-vn-fq*DV_rqxOXF7Jbx>O zZY_>HfB4p(5}se2g9c%H*jV`ryU8<^k7p+(K%fYCL7*h|ys02n!F?NaKI7HAdvIX! z`Sas#(h)jsGX3nc81WQduS2&ZkMY^rUZcvTo2$EeM~{sDP$*$gLNI`Y@5Mo5&KN3; z5-S9fh4;B@h4`f+gDgSbcQ%#33iB-n|e7N=?6kowyVc`zR@G#dC|6)O`o1>C&3-cepiF5Cy;jnPt z-JgbN_RhT0IgbGPOBE%u!q?FGrKiEcm<)Eo2>3-DNbd_lUB-)A`1YX4URST+yA#7 zZWeyBiXKIUzafxsA9{FGNAb#EK$h8`|MjN-S;GClMV|hTFP!Z)IS2ZeDA8<(vwl*^AGD8S6RzP1Ur&~vF+c)7XJ+GA)x2~V6hR5atHlmw&9Odo$KxwOky?r!l z@v8jqhMN$(KWbkx7}%6x-jbGBs9}wb7#17jQW|YGd4lD zgO#zj)e)P}F%@!{pP?>_?RUI>x;*4c4SslnzP`ipuk9F8nhDmIdMy+z@SRk(qEBg@ z_9e3TomMc7=0Ogk+^BChjH$NhFIpg){coa@Sl93>}Kaw)oTvku?`Zj_)jhAs=9nFk6h_b;Msr6 zz`#HYnm>Kn=o!n~fQA)ECWM3Nt{@kfiafc?J$i`vd-6#Q43y8kc4kvQnvK(V$jyyP ztQh^`(V($z@WO8V@pd|81&ZnRGRJu_!gsTYnMF}SK}kVjvH58k{O@Pa?wO3Q%T&tj zrc(RjN`-~GKAXIfmwi{5pH4u~GNg&|1@;Xird9u)EM<1~cw-dbb{>DS$UGI*4i^Sw zc}Tg`3N6MO3$a9=EGMP=#J+mPB3^s#an%q=8jt#Cer3Iijt)pjP#;J=>Ga6rT*s_%omhG>=c#$RVQA zVlgqs$=q(Kngd|Szxg2F@g0ulP&-}@ic?`p9>|^jMsISv3S;AXi4d-HG-{)$lv@5? zuP3>VAH1`m80C_sloaRfMBPxadX1(Ax579x3$w`e4J?n>qi>r`sB6ewcI*x1)W?%k77@+&sOvc-?RY%7*MTv2CKS|e?w9*Fg}a|2NN8vidY==MWX=-~ z54NtT<#bD)_IJh_fNU;7Qc4aP8RD#|=m0K0HAYLmoS2=Q9OhS7$CgX2J>qN6%#qAB zYO}HdBag%FO7ouLImFz83;`a_z{n6~0%))BxtzDxLHsuYS)RSX#?u-zWmeOWR1me+ zk(MqADKeIqx7*TZbKJkCZ);OWSw%$b@~qk!ZvCiFEU4#0K}kjB=y-wjDCGS6mZdM2 z&htFKf260lq$F(YO_*za;cm^t?MtnC)%%0{XO!q64kxD$(r!EC6xY9QX_cYxMds6F zx3|9~bDM1rYPxOP-~OtiJ}__QNsWw+)v7llEq6avFwz;mzr4JRSSFy$eK|VD1diz< zk!cb>J7NObr1Hre06L(Y$umfG6x_v;X}6BDN~SGL*wr@22k zh6Dz7KelUTW@bVNNJvnzs*mjl69&7|b2`4w{`9er>TzD%-^T%8Dkv;y>|JhZ8EI@| zX+oW1=Sfr(&luaoe!g;%t2~pM^4{o%8P5Kvhp%H=FWyAg%DIP+HF9)~Y5cCp34!Qr zm2lfZ`>F$CBpFAvC@0VO`Oq6!?;HuDd!wgbA(7l%GP|woa^;C}g&-I?)+FkoPG%&mcKD zIVs`%{JJJnuo@Z~qr=1Lg@gMlDq4>}_Gr`71SgUb`9Hl?OuiS}T0MG7_xXp;)A8c@%?e`rjed!M%H@txIeOla}Nw8B06GtZ0w=hy`z`K4dp5+Az?Qh z)56#+%9DnenloV9fX#A$ng2^gg{?w#3_cH4$b4D#T3CC65cx0X>#3K}4-C2)gkE>3 zpWbp+2e}sTc-*zb9dX0Gmb3OJvVUxdjotJs=DZ|3eENWOxxWAlIrDv1JLoS>LYk+d z7JoF;n4+>!txxWTk|OP79bfU(Lg?b63I*kfz1OoZr6xI$naSyZ&x6E7aB~9#NiQg% zBw}2?*rUoETC7i;U~yQ?D)cVk1tt$ki=lbc?a z!a^z_lFky@)1+xYMZ-->bhOtJoo>ccwI`vY6UHGzE+Qo42fU-@;bIq~v;hw9&dvcg zI^N02Z;@Rdj$Pb9lZd#O!&^EWMKT4&saIH{Ck&J;&~I#ID2nDr2yW`(i&@+dJL9(#F@+Oo^eM zLYm^g==vtj?VfLy#uI{0uijvASyn#z{GmOyt_x&NB6}ri{{3X!be(N?2|o0IyyYmZF)L7bfkBBmOKnL zLxXfb{f39gcDgA&8j-`(qVb3BA%5oZ zsVTE?oCmMWOkG{VLFw1_w_aQHvvYIdxyBzwx;*dCcce!g2nh#MrA4;${-MiNuf zk&Vk(AM*wALzC8BQ^ie9SQQnT@vwRpcw8+`c)rbhW8;J?3@yODyRvo)p43*JQc!H( zSVdR{Mhu5pR=_nPIXRZ1wmK}Qo3Xg-dUv&-Gr5SH z9y<+}fKuwnnLb~>Q^uy$O!JZ#1R{q$6%rBx-Ev!1G?+G2?|!qZJaHI3pOeigO-ZSX zPSB3|ISlKgkPsxjswz|^XT$^|d$j^h8tOzsJ)~0QdhqK4o2AM=0CDOv2}M?29Rboq zSx|BMt0i zU}tCrB$~W4(}6(DCM``Y{ya3RjJP4+h9`-tXQw&9U`;oNwx6QHVjSLbBzoS1AQGE+ z%B5Cjpm$L9mpd9{dR7u06{)+wmuy!-L4n8lc(`Z82ad8@5Edmg^i>c{W_Eu5^vs0d zHO30!-V}}cuj`R4MiFvWz0T(uPln^kvY<*}eYeVt96+!(r>Js7q@;BWwz%c<;1kx= z|E#I9nTpG78{W4$hjU}N%+S>rF%U+qN8sb4{2VHj<*lOiF8qFADA&NvTaQ|?Eg&}!B2}vT84p4-%r2SRTgf#`XSfHP{Gb9w1Bx!n%0?%t$w7dfBj zgJh(ju#kd^>OD(o!v;{^y}|h&7l($lTvMJZsTL}V zjvgXJW5U2fO_j!!@EZmO1}YsC59+NLvb)S!Vvz_m!pMw7M7y)GlU^(~E;Um%d(>}V z9%K@WjKhrGZ%O6Gd@w# zh@zytr23k;JkC(zxkmExANw}ampx%YUx%Lv4zmc^Nm=wpK0zX4VrrrWQRL`T0P{#gY!goERKSCi58twytr z*+wsmQWQ;ld;9rc9)jY7V_#-R-?sfPbon#U&)*9R#hu=uW#Ho++!SHmw61FGo0^!b z$;s8(btx5zp+DI_4(XLwRNCF&L!+U7)%xY^vo%8G=L&ZvDhH15k!0chl9aEmjs5%-oVm4-Z1W{0YsYjOo+4Nhvu7 zT#3!wJKA8lyav#q)@eHyCHMmS19IJaHLK{QeQmHsp>+1DaZl9W)>@uj2gz4Eh86Bg zIv`rGI+eDy^+mrsS7yv8INGOeUmDw#>D1z6JUR6-Nzv_n}SGS8i7@l9iE)>i<};c`Ux4-I)Ow`e)iLA=8TMX{55XwZv}-*$N&oFUL1 zO3mZH#ra7~xY%h_5fU<1o)rM%^dBm9xz*LNvnNghVnHL#UQhq_jwT>h3u75xsyFUZ zfqqC#oDJ?3za;a|5QJJDNUBM$b~%=<$PW~iP3Num3lFzCS@mDk!ee3a68fDZp}fDJ z5~IKzKby4~KWh$}}2tZ%dK*k=6oN+Pl1L_!mjakD!}2foXHGTgw#I6a-Q_}lvG zm8(24e+x5)2S!=3XsSfLSx#QUY1-PNnH?&du*zZXwW>?!A@?2ILpPjw{awH>IFPik6OyiiGVwIr&t_L}fuiLcR<0!!-Dwlf~_oaWfDI2H~H31gKXL zxIczsvue(BfymC{2RQ=Vv9VFge>UKN=d@7}84Cvk>8ZcY@#d;Pb%tFcuJpFBZL$3U znv6ipEvy$?KPe#D$+76 zMC|3uCvO*3)x4AxTw0p`p;Ydv`FXHB(h_12A=1*9n)osQlXvh+Lzj{k(=4|gXh`=C zgXM&~AVS4q`Jq-x=W3^s#^d4ckq4Il#6tbGbWe9A@#v?h+lxJ?!+C#~)(l7)0hfZ7 zR@m63kdV+WkNbAEK+nP_+!W-@r=T}uFUcUXYHH#?c0)%=ZJ{7QtOB+C_$2_cyl(OY z68lwgk-xmc;4q=!FCHpGL(hxO z94Sr4Q;s030my5KWon0$xUh*Ct~3t;4UPLo@5GGVGZmUxuu-9*H?2qfW6{qp4^{zk z8Rma=#5;|H@^o&>UOw9s#Mia+VNu-`x!MzG1HlZWT$xxl!rTNZ>3c8~uK@bmYF z(vfJp+}zweE{n*KsBM@%+E~$2R*oxk;H=LEDDlB<_W|c4#}}~4(9srjpB4s(=phhL zrm1()IWVW)7-)H-;z}jx)f-P;+N`~r z{IMXbpdhJO33ow~x`}mqiU4UDw*C`t%m-jx2cNpQp^vh8+|K3iGk@}Eb~NUD8R(Q+5Rxm*X1<%YH5dsg#~oE2DRVi z6%{0oR_5mCrBr^d+;~GpYsRl{4_#^ufVFE1_zrSopQ0c){(h;W{exvoFn5^fV1zANhrZrBBv-BulXK{JtgY zfej~3#l|i(fmbl~R|&E}KF0D+zHUP~G9;NRMp4Z*T+?}P(gJ@8NVU})8@SBPDL8%d zG(1~7LX$E}HJewMJh1Tbm#*+$3-F?YX#Qt&d55eSM9`dkbzTBBhwpqgM`0BntibE~n>fUE#@Luo+JZW2O1|*TBOA*8~<#>L$~ffEEwrd~Yh8+t3=^ z9wUt7^fcM^>G8`6NVVwq`ghm1d)v(T;Gu70$cu>|^xJ={laG!;^l_E-viA@q(zl?ly?%oOs2xq;;f6N?2M>SlT9YCi}|4fd;+L zF*pj$H$c4&4a56-@rDu)=!x@8I6H#kW8O1=Al>EUsI!?>R-2V$3h8M-{QcFetG%<* zn0bD_@dw%5#8cOofN+C#)GM+>@@hw(DFWiWcUaXCjpq7$EhU?)n*|K+&+no@%I^Mn zpP<6+xoXgb3xY0r?uMX^+}vCcYyuIsG%tYwFV^7}mgRf{3}izF4<7Cqg>++M2tq)^ z{83f)B}8Bg);Ntv{_!Uc1Z30*2!o)kn5yVCx#K#>W1>I=S)^PFPp1XE<^m3iw(^xO zsE~xn{sZt#d-pOgP#0z0z_3K4PMl`x?%^?h#I@b$4dff^huvCbot9+8NV%`Vxwp4j z7s5M<2~wzU->zml`FT=sNeMpVTWZ2p(t%8R%K%h<#4b~15F^1zd=sitMAd@mwysN0O^vw0qi=!xhs@+?3=>Ww{GvGQn?D! z)625g4`(kTsg+APzb7)A$8%sn^KEyvK4^Sdq|k&!;1}-iY@Gce9dsxdAUbxE^MG~< z$LF2FLFuCVad+JM+wK+#1`YC#Nv(9R5fBwhipHH_iX;G)ZD)4|khdU3+FT={4LdTs z+SJsN)Kt1J8OK|FaqaW4cQuXrY98vRr3wnsR`U%PIR!x~jrVC;FCo|WH)sA0_mi=c zfI?W+%d)ep05mjMhkLGTa1Zgd;a^+$o+61wAbhPIZH+;95CZE%97s2hhtd7>vzI8e zL72TR{B}?}QzebS;EtFu18gw8rB3sxqtmsbw${0A61PwJ#~_af+1j<(kttK~QS|lQ z5E+%9-*ZJ}<@!1|{64lwoBQm%8Y>m&_O3VhLB*@9dXR|Z@4c4CbKkvK_LP?ZUenO% zA(PBi#cJcV-bryu#*u=@=;d>Dj%g|~YB#uEqS1&BVP;{eUt|;DrO>i;0U#txjn?yFqaIcmtX^faMJRMWA+jb)zp%BDUoHJJ!_N#@>-0 zT58TbeSa`d?Cdg%O1LG3gZ4HTwGMk9+{Thvtq%56FvWL)6IqINXF=@IdUSj|wcbS* z)E^^+r$Ql9TcoU;D?j}$65fzE@a}_#x=)4?hs`HjaVm^7%t-=7V|p$rrQI-Op-7n{QXu7>?`p}|9)n3A$p3onDob+VKxmR|k7vCCi9 zX~h)ldw6&$2oeGGt9%twcDyrY4CHKp*lO?SfJ)EJ{lLCacD~#S0Oz#by`VedyWa0b^QRUi@2Y`k!CF zfloFwU_NvUN64`J*eW=al=3P?iwf z1=8oi`w0cbAb)Rfc3PWar^9GS3kWx!LEl612@5BF*8%{+*Tk$Bpbqmzvm6%T$7fkk z|E;IYH;@Kr&AY|`AEaH=6t710G_PVGq+5JHa#T3Nx9<@DdruzD^SoF4bya&r)KpZ> z3(U^L1oZUb>3m*z^?U&Hm_1WwX>f;1o`h?hogHjav;BL~^gG-gBE5^+*h15){+cmhLaRf5w>)o_H1$w8*g6MO=g=g-}9-Rx@W|BWqH1Z=UMuDZZ|i_a(2P-Mb$ZEjRVNSXOf zAr$lrHV(-Zy`|PKunFH-AFDOQg7`azkp#5&I#J-!&^AiNCyT?gt3#xviT;UyhaCSZ z{A|g0Y@PdBP<3J4{F9Ns7$t1V<`sA3ZM^BfrMokys%_4SRPRq^wo z@EK_;Ln*SyMBLoO+}vLpT}fzX_`D>^FS7m#Oc~2t^p5@0+>|jEMDji6)7{aPBH)R< zuHi0t8i}z$x0B7m6aCV{f&xda=Gxlqj0}Fo2de;R;P9S7Z<+^wV`OHWn8Gh+6`umk z5y+`)La{QmemH&nlI`aQ%(qDWyY29o2oG}usNX-mg%=Ev{^x#VVofN2>W)1v<3G5r zy`7!iogKz^@Lo;sAW)@S->9knDV?^7hJl@u6a@^g6Tlj-@Mr{hGZ$^fTM8l~2$Wf6 zSe>jul7kgm?IxqAIb2J~e$UB*(8i)_L*z((&)tIeRn&JInf>W5So1 z5&1RMr`eT25w;V5d*O%l@~@Lt9$`*4$x?%hL_hI8HSoT8^@1QA*9yl{qR|$}b1Fav zdAR!y(ZBt<6tuwc6la?PcaicL`Inwr$KnRIQn_m!H4TJ>3^DeAq>5JUouwsDWSlf0 zC%p5lq9?I3ltG>B2puEiC~Jx4Y6+*GZ1~DfzE8J*N%M-5QtHX+1~p*3uOE}3pl`#m za_Y@{h)8q1TqwhSaQz;bVCSGZEixR1*Jh~snYz2V%CwL)mO*qrwtR7*$o+e|+j>(n z4Upd$^pDfO90I;Xsq<@<#K)_!I@J6P&3P50qvJ&;I-)K;gnEicO9^hKavPiL8JX)j z9?ruQ&Kh8IIY;z3>jQX%XRNWtJjmthP!kZ^(N}G`+3nj)&0bek;lttK6(%ZW)?zL< zm8Yl107-i8Ef#fPuz}gmJ4Y$4aPbU6EMfu;aXUQwCrXH{Ng`HZ)6YAFh+~N?bIrM% zr7kF{F2X9#&&%)s>rSqh{yaNUI_UIh`W~QffOg*ON7SPz!WS18`%8JD(cNc!WMXN` z-Psb@p?7jw$sfoF5V$2CuaqRDr^X~e=qK^8y5|;RK=R!maUdk5r2lK-0!9)?6zGON zm)MPH2J+d|!5+l^c3;-BniT1|9)h;J3@uvvm;Nu zeplEN5lsUN;UWM!03ZSd_1OPotUWh4xEJ;f9tS(eunBXprzqS>a7EqMjXreP=l&4L z$>3bWnQ{JSOvvA+3HZto3@;k3Uzxypf0&GdBKYSr1k5|iYE4rm-R+3@?NG>jkT{($ zHUf=|r+VJKYDahEED#_-bbNcRm%N%wGk-jXkgbJQR@w!^WEyRK85z|RwwP_PocyDC zn6U%7`2GETg6a%_z6@j*-n=5zl5-r_F*AF}JnaeTC7+yBQmE>QO-;=Jc_VhNp{1#& zs%jkzVQQ=Fb8mq4b8rv`Y76~`$UxIvNk}N6k%pL7^J?XHjRP=bsOVZBm>D(8tWOH$ zRY7YcQPIGkRfDiu>F1rGX?AN11L6(T z7K#s^kM}nMTApSSd*`NFHsvFA?5coE1OO_sdJuum5UwrrJ02dMJ4(ko;~@~85)!n? zB;ymFuWfrMQ*gk)e(nDB*cg8FP8 zC-WR73CS|;@qPA8p^Bb@!kL6tOjXSEBGCcFv}s(Pzf9L$Vcj_O_Wr@dV^Ff=eoHJY z{MuQzxoJc$lI;DF7Y9r!0o@Kt4Rk6;jF3jgbS%=73{xcT9x=q)(Z)+n%kyqi5rkt$ z+~|IfUn@f5s;ei#p-^=>)<<9Ke70F^Hf2Qv_ohRGk2ihsO+S}lESr@iqz x9AJE8#=s3k(iD$svELGo|NaL_@_+x+BR=0U{vG>yo+|`A#Dt_jmI&zh{ttLuC*lAA literal 30147 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 * { - margin-left: $spacing-12; - margin-right: $spacing-12; - } - - > h2 { - color: $tertiary-content; - font: var(--cpd-font-body-sm-medium); - margin: $spacing-12; - } - - .mx_BaseCard_Button { - padding: 10px; - padding-inline-start: $spacing-12; - margin: 0; - position: relative; - font: var(--cpd-font-heading-sm-medium); - height: 20px; - overflow: hidden; - white-space: nowrap; - text-overflow: ellipsis; - display: flex; - - .mx_BaseCard_Button_sublabel { - color: $tertiary-content; - margin-left: auto; - } - - &:hover { - background-color: rgba(141, 151, 165, 0.1); - } - - &.mx_AccessibleButton_disabled { - padding-right: $spacing-12; - &::after { - content: unset; - } - } - } - } - .mx_BaseCard_footer { padding-top: $spacing-4; text-align: center; diff --git a/res/css/views/right_panel/_ExtensionsCard.pcss b/res/css/views/right_panel/_ExtensionsCard.pcss new file mode 100644 index 00000000000..ea5431fb368 --- /dev/null +++ b/res/css/views/right_panel/_ExtensionsCard.pcss @@ -0,0 +1,145 @@ +/* +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_ExtensionsCard { + --cpd-separator-inset: var(--cpd-space-4x); + --cpd-separator-spacing: var(--cpd-space-4x); + + .mx_BaseCard_header { + /* Hide the line between the header and the body of the card */ + border-block-end: none; + + /* Styling for the "Add extensions" button */ + button { + width: 100%; + } + } + + .mx_AutoHideScrollbar { + padding: 0 var(--cpd-space-4x); + box-sizing: border-box; + } + + .mx_ExtensionsCard_container { + text-align: center; + margin: $spacing-20 var(--cpd-space-4x) 0; + } + + .mx_ExtensionsCard_Button { + /* this button is special so we have to override some of the original styling */ + /* as we will be applying it in its children */ + padding: 0; + height: auto; + color: $tertiary-content; + position: relative; + + .mx_WidgetAvatar { + flex-shrink: 0; + } + + .mx_ExtensionsCard_icon_app { + padding: var(--cpd-space-2x) var(--cpd-space-12x) var(--cpd-space-2x) var(--cpd-space-3x); + text-overflow: ellipsis; + overflow: hidden; + display: flex; + align-items: center; + + p { + margin: 0 var(--cpd-space-3x); + color: $primary-content; + } + } + + .mx_ExtensionsCard_app_pinToggle, + .mx_ExtensionsCard_app_options { + position: absolute; + top: 0; + height: 100%; /* to give bigger interactive zone */ + width: 24px; + padding: var(--cpd-space-3x) var(--cpd-space-1x); + box-sizing: border-box; + min-width: 24px; /* prevent flexbox crushing */ + + &:hover { + &::after { + content: ""; + position: absolute; + height: 24px; + width: 24px; + top: var(--cpd-space-2x); /* equal to padding-top of parent */ + left: 0; + border-radius: 12px; + background-color: rgba(141, 151, 165, 0.1); + } + } + + &::before { + content: ""; + position: absolute; + height: 16px; + width: 16px; + mask-repeat: no-repeat; + mask-position: center; + mask-size: 16px; + background-color: $icon-button-color; + } + } + + .mx_ExtensionsCard_app_pinToggle { + right: 8px; + + &::before { + mask-image: url("$(res)/img/element-icons/room/pin-upright.svg"); + } + } + + .mx_ExtensionsCard_app_options { + right: 32px; /* 24 + 8 */ + &::before { + mask-image: url("$(res)/img/element-icons/room/ellipsis.svg"); + } + } + + &.mx_ExtensionsCard_Button_pinned { + &::after { + opacity: 0.2; + } + + .mx_ExtensionsCard_app_pinToggle::before { + background-color: $accent; + } + } + + &::before { + content: unset; + } + + &::after { + top: var(--cpd-space-2x); /* re-align based on the height change */ + pointer-events: none; /* pass through to the real button */ + } + } + + /* Set layout for everyone button */ + a[data-kind="primary"] { + margin-top: var(--cpd-space-10x); + } + + .mx_EmptyState::before { + /* Overlap the Add extensions button */ + top: -76px; + } +} diff --git a/res/css/views/right_panel/_RoomSummaryCard.pcss b/res/css/views/right_panel/_RoomSummaryCard.pcss index 75f0178cddf..5c3cab320ca 100644 --- a/res/css/views/right_panel/_RoomSummaryCard.pcss +++ b/res/css/views/right_panel/_RoomSummaryCard.pcss @@ -33,24 +33,6 @@ limitations under the License. text-overflow: ellipsis; } - .mx_RoomSummaryCard_aboutGroup { - .mx_RoomSummaryCard_Button { - padding-left: 44px; - - &::before { - content: ""; - position: absolute; - top: 8px; - left: 10px; - height: 24px; - width: 24px; - mask-repeat: no-repeat; - mask-position: center; - background-color: $icon-button-color; - } - } - } - .mx_RoomSummaryCard_topic { padding: 0 12px; color: var(--cpd-color-text-secondary); @@ -99,131 +81,6 @@ limitations under the License. } } - .mx_RoomSummaryCard_appsGroup { - .mx_RoomSummaryCard_Button { - /* this button is special so we have to override some of the original styling */ - /* as we will be applying it in its children */ - padding: 0; - height: auto; - color: $tertiary-content; - - .mx_RoomSummaryCard_icon_app { - padding: 10px 48px 10px 12px; /* based on typical mx_RoomSummaryCard_Button padding */ - text-overflow: ellipsis; - overflow: hidden; - display: flex; - justify-content: center; - span { - /* Center aligned and Spacing matched with the About section above the Widgets section */ - margin-right: 10px; - display: flex; - justify-content: center; - align-items: center; - color: $primary-content; - } - } - - .mx_RoomSummaryCard_app_pinToggle, - .mx_RoomSummaryCard_app_maximiseToggle, - .mx_RoomSummaryCard_app_options { - position: absolute; - top: 0; - height: 100%; /* to give bigger interactive zone */ - width: 24px; - padding: 12px 4px; - box-sizing: border-box; - min-width: 24px; /* prevent flexbox crushing */ - - &:hover { - &::after { - content: ""; - position: absolute; - height: 24px; - width: 24px; - top: 8px; /* equal to padding-top of parent */ - left: 0; - border-radius: 12px; - background-color: rgba(141, 151, 165, 0.1); - } - } - - &::before { - content: ""; - position: absolute; - height: 16px; - width: 16px; - mask-repeat: no-repeat; - mask-position: center; - mask-size: 16px; - background-color: $icon-button-color; - } - } - - .mx_RoomSummaryCard_app_pinToggle { - right: 8px; - - &::before { - mask-image: url("$(res)/img/element-icons/room/pin-upright.svg"); - } - } - .mx_RoomSummaryCard_app_maximiseToggle { - right: 32px; /* 24 + 8 */ - - &::before { - mask-size: 14px; - mask-image: url("$(res)/img/element-icons/maximise-expand.svg"); - } - } - - .mx_RoomSummaryCard_app_options { - right: 56px; /* 2*24 + 8 */ - display: none; - &::before { - mask-image: url("$(res)/img/element-icons/room/ellipsis.svg"); - } - } - - &.mx_RoomSummaryCard_Button_pinned { - &::after { - opacity: 0.2; - } - - .mx_RoomSummaryCard_app_pinToggle::before { - background-color: $accent; - } - } - - &.mx_RoomSummaryCard_Button_maximised { - &::after { - opacity: 0.2; - } - - .mx_RoomSummaryCard_app_maximiseToggle::before { - background-color: $accent; - } - } - - &:hover { - .mx_RoomSummaryCard_icon_app { - padding-right: 72px; - } - - .mx_RoomSummaryCard_app_options { - display: unset; - } - } - - &::before { - content: unset; - } - - &::after { - top: 8px; /* re-align based on the height change */ - pointer-events: none; /* pass through to the real button */ - } - } - } - .mx_AccessibleButton_kind_link { margin-top: 12px; margin-bottom: 12px; diff --git a/res/themes/light-high-contrast/css/_light-high-contrast.pcss b/res/themes/light-high-contrast/css/_light-high-contrast.pcss index a306e769b00..213c6414401 100644 --- a/res/themes/light-high-contrast/css/_light-high-contrast.pcss +++ b/res/themes/light-high-contrast/css/_light-high-contrast.pcss @@ -64,14 +64,6 @@ $accent-1400: var(--cpd-color-green-1400); outline-offset: 2px; } -/* Add padding, so the outline is not chopped off on the left */ -.mx_BaseCard { - padding-left: 4px !important; /* Remove 4 to allow 4 in mx_BaseCard_Group */ -} -.mx_BaseCard_Group { - padding-left: 4px !important; -} - .mx_BasicMessageComposer .mx_BasicMessageComposer_inputEmpty > :first-child::before { color: $secondary-content; opacity: 1 !important; diff --git a/src/components/structures/RightPanel.tsx b/src/components/structures/RightPanel.tsx index bc80692459a..1d6bf101b6e 100644 --- a/src/components/structures/RightPanel.tsx +++ b/src/components/structures/RightPanel.tsx @@ -43,6 +43,7 @@ import { IRightPanelCard, IRightPanelCardState } from "../../stores/right-panel/ import { Action } from "../../dispatcher/actions"; import { XOR } from "../../@types/common"; import { RightPanelTabs } from "../views/right_panel/RightPanelTabs"; +import ExtensionsCard from "../views/right_panel/ExtensionsCard"; interface BaseProps { overwriteCard?: IRightPanelCard; // used to display a custom card and ignoring the RightPanelStore (used for UserView) @@ -306,6 +307,12 @@ export default class RightPanel extends React.Component { } break; + case RightPanelPhases.Extensions: + if (!!this.props.room) { + card = ; + } + break; + case RightPanelPhases.Widget: if (!!this.props.room && !!cardState?.widgetId) { card = ; @@ -315,7 +322,7 @@ export default class RightPanel extends React.Component { return (

); diff --git a/src/components/views/right_panel/BaseCard.tsx b/src/components/views/right_panel/BaseCard.tsx index fc7b1bcf695..8443da220e7 100644 --- a/src/components/views/right_panel/BaseCard.tsx +++ b/src/components/views/right_panel/BaseCard.tsx @@ -41,26 +41,11 @@ interface IProps { onKeyDown?(ev: KeyboardEvent): void; cardState?: any; ref?: Ref; - // Ref for the 'close' button the the card + // Ref for the 'close' button the card closeButtonRef?: Ref; children: ReactNode; } -interface IGroupProps { - className?: string; - title: string; - children: ReactNode; -} - -export const Group: React.FC = ({ className, title, children }) => { - return ( -
-

{title}

- {children} -
- ); -}; - const BaseCard: React.FC = forwardRef( ( { diff --git a/src/components/views/right_panel/ExtensionsCard.tsx b/src/components/views/right_panel/ExtensionsCard.tsx new file mode 100644 index 00000000000..22ea8bad99f --- /dev/null +++ b/src/components/views/right_panel/ExtensionsCard.tsx @@ -0,0 +1,214 @@ +/* +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, { useEffect, useMemo, useState } from "react"; +import { Room } from "matrix-js-sdk/src/matrix"; +import classNames from "classnames"; +import { Button, Link, Separator, Text } from "@vector-im/compound-web"; +import { Icon as PlusIcon } from "@vector-im/compound-design-tokens/icons/plus.svg"; +import { Icon as ExtensionsIcon } from "@vector-im/compound-design-tokens/icons/extensions.svg"; + +import BaseCard from "./BaseCard"; +import WidgetUtils, { useWidgets } from "../../../utils/WidgetUtils"; +import { _t } from "../../../languageHandler"; +import { ChevronFace, ContextMenuTooltipButton, useContextMenu } from "../../structures/ContextMenu"; +import { WidgetContextMenu } from "../context_menus/WidgetContextMenu"; +import UIStore from "../../../stores/UIStore"; +import RightPanelStore from "../../../stores/right-panel/RightPanelStore"; +import { IApp } from "../../../stores/WidgetStore"; +import { RightPanelPhases } from "../../../stores/right-panel/RightPanelStorePhases"; +import { Container, MAX_PINNED, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore"; +import AccessibleButton from "../elements/AccessibleButton"; +import WidgetAvatar from "../avatars/WidgetAvatar"; +import { IntegrationManagers } from "../../../integrations/IntegrationManagers"; +import EmptyState from "./EmptyState"; + +interface Props { + room: Room; + onClose(): void; +} + +interface IAppRowProps { + app: IApp; + room: Room; +} + +const AppRow: React.FC = ({ app, room }) => { + const name = WidgetUtils.getWidgetName(app); + const [canModifyWidget, setCanModifyWidget] = useState(); + + useEffect(() => { + setCanModifyWidget(WidgetUtils.canUserModifyWidgets(room.client, room.roomId)); + }, [room.client, room.roomId]); + + const onOpenWidgetClick = (): void => { + RightPanelStore.instance.pushCard({ + phase: RightPanelPhases.Widget, + state: { widgetId: app.id }, + }); + }; + + const isPinned = WidgetLayoutStore.instance.isInContainer(room, app, Container.Top); + const togglePin = isPinned + ? () => { + WidgetLayoutStore.instance.moveToContainer(room, app, Container.Right); + } + : () => { + WidgetLayoutStore.instance.moveToContainer(room, app, Container.Top); + }; + + const [menuDisplayed, handle, openMenu, closeMenu] = useContextMenu(); + let contextMenu; + if (menuDisplayed) { + const rect = handle.current?.getBoundingClientRect(); + const rightMargin = rect?.right ?? 0; + const topMargin = rect?.top ?? 0; + contextMenu = ( + + ); + } + + const cannotPin = !isPinned && !WidgetLayoutStore.instance.canAddToContainer(room, Container.Top); + + let pinTitle: string; + if (cannotPin) { + pinTitle = _t("right_panel|pinned_messages|limits", { count: MAX_PINNED }); + } else { + pinTitle = isPinned ? _t("action|unpin") : _t("action|pin"); + } + + const isMaximised = WidgetLayoutStore.instance.isInContainer(room, app, Container.Center); + + let openTitle = ""; + if (isPinned) { + openTitle = _t("widget|unpin_to_view_right_panel"); + } else if (isMaximised) { + openTitle = _t("widget|close_to_view_right_panel"); + } + + const classes = classNames("mx_BaseCard_Button mx_ExtensionsCard_Button", { + mx_ExtensionsCard_Button_pinned: isPinned, + }); + + return ( +
+ + + + {name} + + + + {canModifyWidget && ( + + )} + + + + {contextMenu} +
+ ); +}; + +/** + * A right panel card displaying a list of widgets in the room and allowing the user to manage them. + * @param room the room to manage widgets for + * @param onClose callback when the card is closed + */ +const ExtensionsCard: React.FC = ({ room, onClose }) => { + const apps = useWidgets(room); + // Filter out virtual widgets + const realApps = useMemo(() => apps.filter((app) => app.eventId !== undefined), [apps]); + + const onManageIntegrations = (): void => { + const managers = IntegrationManagers.sharedInstance(); + if (!managers.hasManager()) { + managers.openNoManagerDialog(); + } else { + // noinspection JSIgnoredPromiseFromCall + managers.getPrimaryManager()?.open(room); + } + }; + + // The button is in the header to keep it outside the scrollable region + const header = ( + + ); + + let body: JSX.Element; + if (realApps.length < 1) { + body = ( + + ); + } else { + let copyLayoutBtn: JSX.Element | null = null; + if (WidgetLayoutStore.instance.canCopyLayoutToRoom(room)) { + copyLayoutBtn = ( + WidgetLayoutStore.instance.copyLayoutToRoom(room)}> + {_t("widget|set_room_layout")} + + ); + } + + body = ( + <> + + {realApps.map((app) => ( + + ))} + {copyLayoutBtn} + + ); + } + + return ( + + {body} + + ); +}; + +export default ExtensionsCard; diff --git a/src/components/views/right_panel/RightPanelTabs.tsx b/src/components/views/right_panel/RightPanelTabs.tsx index fc2eeb17fac..300856e28fd 100644 --- a/src/components/views/right_panel/RightPanelTabs.tsx +++ b/src/components/views/right_panel/RightPanelTabs.tsx @@ -16,6 +16,7 @@ limitations under the License. import React, { useRef } from "react"; import { NavBar, NavItem } from "@vector-im/compound-web"; +import { Room } from "matrix-js-sdk/src/matrix"; import { _t } from "../../../languageHandler"; import { RightPanelPhases } from "../../../stores/right-panel/RightPanelStorePhases"; @@ -24,17 +25,27 @@ import PosthogTrackers from "../../../PosthogTrackers"; import { useDispatcher } from "../../../hooks/useDispatcher"; import dispatcher from "../../../dispatcher/dispatcher"; import { Action } from "../../../dispatcher/actions"; +import SettingsStore from "../../../settings/SettingsStore"; +import { UIComponent, UIFeature } from "../../../settings/UIFeature"; +import { shouldShowComponent } from "../../../customisations/helpers/UIComponents"; +import { useIsVideoRoom } from "../../../utils/video-rooms"; function shouldShowTabsForPhase(phase?: RightPanelPhases): boolean { - const tabs = [RightPanelPhases.RoomSummary, RightPanelPhases.RoomMemberList, RightPanelPhases.ThreadPanel]; + const tabs = [ + RightPanelPhases.RoomSummary, + RightPanelPhases.RoomMemberList, + RightPanelPhases.ThreadPanel, + RightPanelPhases.Extensions, + ]; return !!phase && tabs.includes(phase); } type Props = { + room?: Room; phase: RightPanelPhases; }; -export const RightPanelTabs: React.FC = ({ phase }): JSX.Element | null => { +export const RightPanelTabs: React.FC = ({ phase, room }): JSX.Element | null => { const threadsTabRef = useRef(null); useDispatcher(dispatcher, (payload) => { @@ -45,6 +56,8 @@ export const RightPanelTabs: React.FC = ({ phase }): JSX.Element | null = } }); + const isVideoRoom = useIsVideoRoom(room); + if (!shouldShowTabsForPhase(phase)) return null; return ( @@ -81,6 +94,20 @@ export const RightPanelTabs: React.FC = ({ phase }): JSX.Element | null = > {_t("common|threads")} + {SettingsStore.getValue(UIFeature.Widgets) && + !isVideoRoom && + shouldShowComponent(UIComponent.AddIntegrations) && ( + { + RightPanelStore.instance.pushCard({ phase: RightPanelPhases.Extensions }, true); + }} + active={phase === RightPanelPhases.Extensions} + > + {_t("common|extensions")} + + )} ); }; diff --git a/src/components/views/right_panel/RoomSummaryCard.tsx b/src/components/views/right_panel/RoomSummaryCard.tsx index 9896289e25c..bb35242bc79 100644 --- a/src/components/views/right_panel/RoomSummaryCard.tsx +++ b/src/components/views/right_panel/RoomSummaryCard.tsx @@ -14,16 +14,7 @@ See the License for the specific language governing permissions and limitations under the License. */ -import React, { - ChangeEvent, - SyntheticEvent, - useCallback, - useContext, - useEffect, - useMemo, - useRef, - useState, -} from "react"; +import React, { ChangeEvent, SyntheticEvent, useContext, useEffect, useRef, useState } from "react"; import classNames from "classnames"; import { MenuItem, @@ -55,35 +46,23 @@ import { EventType, JoinRule, Room, RoomStateEvent } from "matrix-js-sdk/src/mat import MatrixClientContext from "../../../contexts/MatrixClientContext"; import { useIsEncrypted } from "../../../hooks/useIsEncrypted"; -import BaseCard, { Group } from "./BaseCard"; +import BaseCard from "./BaseCard"; import { _t } from "../../../languageHandler"; import RoomAvatar from "../avatars/RoomAvatar"; -import AccessibleButton from "../elements/AccessibleButton"; import defaultDispatcher from "../../../dispatcher/dispatcher"; import { RightPanelPhases } from "../../../stores/right-panel/RightPanelStorePhases"; import Modal from "../../../Modal"; import ShareDialog from "../dialogs/ShareDialog"; -import { useEventEmitter, useEventEmitterState } from "../../../hooks/useEventEmitter"; -import WidgetUtils from "../../../utils/WidgetUtils"; -import { IntegrationManagers } from "../../../integrations/IntegrationManagers"; -import SettingsStore from "../../../settings/SettingsStore"; -import WidgetAvatar from "../avatars/WidgetAvatar"; -import WidgetStore, { IApp } from "../../../stores/WidgetStore"; +import { useEventEmitterState } from "../../../hooks/useEventEmitter"; import { E2EStatus } from "../../../utils/ShieldUtils"; import { RoomPermalinkCreator } from "../../../utils/permalinks/Permalinks"; import RoomContext, { TimelineRenderingType } from "../../../contexts/RoomContext"; -import { UIComponent, UIFeature } from "../../../settings/UIFeature"; -import { ChevronFace, ContextMenuTooltipButton, useContextMenu } from "../../structures/ContextMenu"; -import { WidgetContextMenu } from "../context_menus/WidgetContextMenu"; import { useFeatureEnabled } from "../../../hooks/useSettings"; import { usePinnedEvents } from "./PinnedMessagesCard"; -import { Container, MAX_PINNED, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore"; import RoomName from "../elements/RoomName"; -import UIStore from "../../../stores/UIStore"; import ExportDialog from "../dialogs/ExportDialog"; import RightPanelStore from "../../../stores/right-panel/RightPanelStore"; import PosthogTrackers from "../../../PosthogTrackers"; -import { shouldShowComponent } from "../../../customisations/helpers/UIComponents"; import { PollHistoryDialog } from "../dialogs/PollHistoryDialog"; import { Flex } from "../../utils/Flex"; import RoomListStore, { LISTS_UPDATE_EVENT } from "../../../stores/room-list/RoomListStore"; @@ -111,182 +90,6 @@ interface IProps { focusRoomSearch?: boolean; } -interface IAppsSectionProps { - room: Room; -} - -export const useWidgets = (room: Room): IApp[] => { - const [apps, setApps] = useState(() => WidgetStore.instance.getApps(room.roomId)); - - const updateApps = useCallback(() => { - // Copy the array so that we always trigger a re-render, as some updates mutate the array of apps/settings - setApps([...WidgetStore.instance.getApps(room.roomId)]); - }, [room]); - - useEffect(updateApps, [room, updateApps]); - useEventEmitter(WidgetStore.instance, room.roomId, updateApps); - useEventEmitter(WidgetLayoutStore.instance, WidgetLayoutStore.emissionForRoom(room), updateApps); - - return apps; -}; - -interface IAppRowProps { - app: IApp; - room: Room; -} - -const AppRow: React.FC = ({ app, room }) => { - const name = WidgetUtils.getWidgetName(app); - const dataTitle = WidgetUtils.getWidgetDataTitle(app); - const subtitle = dataTitle && " - " + dataTitle; - const [canModifyWidget, setCanModifyWidget] = useState(); - - useEffect(() => { - setCanModifyWidget(WidgetUtils.canUserModifyWidgets(room.client, room.roomId)); - }, [room.client, room.roomId]); - - const onOpenWidgetClick = (): void => { - RightPanelStore.instance.pushCard({ - phase: RightPanelPhases.Widget, - state: { widgetId: app.id }, - }); - }; - - const isPinned = WidgetLayoutStore.instance.isInContainer(room, app, Container.Top); - const togglePin = isPinned - ? () => { - WidgetLayoutStore.instance.moveToContainer(room, app, Container.Right); - } - : () => { - WidgetLayoutStore.instance.moveToContainer(room, app, Container.Top); - }; - - const [menuDisplayed, handle, openMenu, closeMenu] = useContextMenu(); - let contextMenu; - if (menuDisplayed) { - const rect = handle.current?.getBoundingClientRect(); - const rightMargin = rect?.right ?? 0; - const topMargin = rect?.top ?? 0; - contextMenu = ( - - ); - } - - const cannotPin = !isPinned && !WidgetLayoutStore.instance.canAddToContainer(room, Container.Top); - - let pinTitle: string; - if (cannotPin) { - pinTitle = _t("right_panel|pinned_messages|limits", { count: MAX_PINNED }); - } else { - pinTitle = isPinned ? _t("action|unpin") : _t("action|pin"); - } - - const isMaximised = WidgetLayoutStore.instance.isInContainer(room, app, Container.Center); - const toggleMaximised = isMaximised - ? () => { - WidgetLayoutStore.instance.moveToContainer(room, app, Container.Right); - } - : () => { - WidgetLayoutStore.instance.moveToContainer(room, app, Container.Center); - }; - - const maximiseTitle = isMaximised ? _t("action|close") : _t("action|maximise"); - - let openTitle = ""; - if (isPinned) { - openTitle = _t("widget|unpin_to_view_right_panel"); - } else if (isMaximised) { - openTitle = _t("widget|close_to_view_right_panel"); - } - - const classes = classNames("mx_BaseCard_Button mx_RoomSummaryCard_Button", { - mx_RoomSummaryCard_Button_pinned: isPinned, - mx_RoomSummaryCard_Button_maximised: isMaximised, - }); - - return ( -
- - - {name} - {subtitle} - - - {canModifyWidget && ( - - )} - - - - - {contextMenu} -
- ); -}; - -const AppsSection: React.FC = ({ room }) => { - const apps = useWidgets(room); - // Filter out virtual widgets - const realApps = useMemo(() => apps.filter((app) => app.eventId !== undefined), [apps]); - - const onManageIntegrations = (): void => { - const managers = IntegrationManagers.sharedInstance(); - if (!managers.hasManager()) { - managers.openNoManagerDialog(); - } else { - // noinspection JSIgnoredPromiseFromCall - managers.getPrimaryManager()?.open(room); - } - }; - - let copyLayoutBtn: JSX.Element | null = null; - if (realApps.length > 0 && WidgetLayoutStore.instance.canCopyLayoutToRoom(room)) { - copyLayoutBtn = ( - WidgetLayoutStore.instance.copyLayoutToRoom(room)}> - {_t("widget|set_room_layout")} - - ); - } - - return ( - - {realApps.map((app) => ( - - ))} - {copyLayoutBtn} - - {realApps.length > 0 ? _t("right_panel|edit_integrations") : _t("right_panel|add_integrations")} - - - ); -}; - const onRoomFilesClick = (): void => { RightPanelStore.instance.pushCard({ phase: RightPanelPhases.FilePanel }, true); }; @@ -622,10 +425,6 @@ const RoomSummaryCard: React.FC = ({ onSelect={onLeaveRoomClick} /> - - {SettingsStore.getValue(UIFeature.Widgets) && - !isVideoRoom && - shouldShowComponent(UIComponent.AddIntegrations) && } ); }; diff --git a/src/components/views/right_panel/WidgetCard.tsx b/src/components/views/right_panel/WidgetCard.tsx index ca7cdebb21f..210e673556a 100644 --- a/src/components/views/right_panel/WidgetCard.tsx +++ b/src/components/views/right_panel/WidgetCard.tsx @@ -19,10 +19,9 @@ import { Room } from "matrix-js-sdk/src/matrix"; import MatrixClientContext from "../../../contexts/MatrixClientContext"; import BaseCard from "./BaseCard"; -import WidgetUtils from "../../../utils/WidgetUtils"; +import WidgetUtils, { useWidgets } from "../../../utils/WidgetUtils"; import AppTile from "../elements/AppTile"; import { _t } from "../../../languageHandler"; -import { useWidgets } from "./RoomSummaryCard"; import { ChevronFace, ContextMenuButton, useContextMenu } from "../../structures/ContextMenu"; import { WidgetContextMenu } from "../context_menus/WidgetContextMenu"; import { Container, WidgetLayoutStore } from "../../../stores/widgets/WidgetLayoutStore"; diff --git a/src/components/views/rooms/LegacyRoomHeader.tsx b/src/components/views/rooms/LegacyRoomHeader.tsx index c6fa28fc7ca..b3f76e980f1 100644 --- a/src/components/views/rooms/LegacyRoomHeader.tsx +++ b/src/components/views/rooms/LegacyRoomHeader.tsx @@ -54,7 +54,7 @@ import LegacyCallHandler, { LegacyCallHandlerEvent } from "../../../LegacyCallHa import { useFeatureEnabled, useSettingValue } from "../../../hooks/useSettings"; import SdkConfig from "../../../SdkConfig"; import { useEventEmitterState, useTypedEventEmitterState } from "../../../hooks/useEventEmitter"; -import { useWidgets } from "../right_panel/RoomSummaryCard"; +import { useWidgets } from "../../../utils/WidgetUtils"; import { WidgetType } from "../../../widgets/WidgetType"; import { useCall, useLayout } from "../../../hooks/useCall"; import { getJoinedNonFunctionalMembers } from "../../../utils/room/getJoinedNonFunctionalMembers"; diff --git a/src/hooks/room/useRoomCall.ts b/src/hooks/room/useRoomCall.ts index 8dc18040a12..65be125bf32 100644 --- a/src/hooks/room/useRoomCall.ts +++ b/src/hooks/room/useRoomCall.ts @@ -22,7 +22,7 @@ import { useFeatureEnabled } from "../useSettings"; import SdkConfig from "../../SdkConfig"; import { useEventEmitter, useEventEmitterState } from "../useEventEmitter"; import LegacyCallHandler, { LegacyCallHandlerEvent } from "../../LegacyCallHandler"; -import { useWidgets } from "../../components/views/right_panel/RoomSummaryCard"; +import { useWidgets } from "../../utils/WidgetUtils"; import { WidgetType } from "../../widgets/WidgetType"; import { useCall, useConnectionState, useParticipantCount } from "../useCall"; import { useRoomMemberCount } from "../useRoomMembers"; diff --git a/src/i18n/strings/en_EN.json b/src/i18n/strings/en_EN.json index a542fc7c601..a17b04a9f69 100644 --- a/src/i18n/strings/en_EN.json +++ b/src/i18n/strings/en_EN.json @@ -474,6 +474,7 @@ "encrypted": "Encrypted", "encryption_enabled": "Encryption enabled", "error": "Error", + "extensions": "Extensions", "faq": "FAQ", "favourites": "Favourites", "feedback": "Feedback", @@ -1830,10 +1831,11 @@ "restore_failed_error": "Unable to restore backup" }, "right_panel": { - "add_integrations": "Add widgets, bridges & bots", + "add_integrations": "Add extensions", "add_topic": "Add topic", - "edit_integrations": "Edit widgets, bridges & bots", "export_chat_button": "Export chat", + "extensions_empty_description": "Select “%(addIntegrations)s” to browse and add extensions to this room", + "extensions_empty_title": "Boost productivity with more tools, widgets and bots", "files_button": "Files", "info": "Info", "pinned_messages": { @@ -4067,7 +4069,7 @@ "title": "Allow this widget to verify your identity" }, "popout": "Popout widget", - "set_room_layout": "Set my room layout for everyone", + "set_room_layout": "Set layout for everyone", "shared_data_avatar": "Your profile picture URL", "shared_data_device_id": "Your device ID", "shared_data_lang": "Your language", diff --git a/src/stores/right-panel/RightPanelStorePhases.ts b/src/stores/right-panel/RightPanelStorePhases.ts index 2353d3fe43f..4cae6768302 100644 --- a/src/stores/right-panel/RightPanelStorePhases.ts +++ b/src/stores/right-panel/RightPanelStorePhases.ts @@ -28,6 +28,7 @@ export enum RightPanelPhases { Widget = "Widget", PinnedMessages = "PinnedMessages", Timeline = "Timeline", + Extensions = "Extensions", Room3pidMemberInfo = "Room3pidMemberInfo", diff --git a/src/utils/WidgetUtils.ts b/src/utils/WidgetUtils.ts index 3272a14e4e9..40712f633a1 100644 --- a/src/utils/WidgetUtils.ts +++ b/src/utils/WidgetUtils.ts @@ -15,6 +15,7 @@ See the License for the specific language governing permissions and limitations under the License. */ +import { useCallback, useEffect, useState } from "react"; import { base32 } from "rfc4648"; import { IWidget, IWidgetData } from "matrix-widget-api"; import { Room, ClientEvent, MatrixClient, RoomStateEvent, MatrixEvent } from "matrix-js-sdk/src/matrix"; @@ -32,8 +33,10 @@ import { WidgetType } from "../widgets/WidgetType"; import { Jitsi } from "../widgets/Jitsi"; import { objectClone } from "./objects"; import { _t } from "../languageHandler"; -import { IApp, isAppWidget } from "../stores/WidgetStore"; +import WidgetStore, { IApp, isAppWidget } from "../stores/WidgetStore"; import { parseUrl } from "./UrlUtils"; +import { useEventEmitter } from "../hooks/useEventEmitter"; +import { WidgetLayoutStore } from "../stores/widgets/WidgetLayoutStore"; // How long we wait for the state event echo to come back from the server // before waitFor[Room/User]Widget rejects its promise @@ -562,3 +565,22 @@ export default class WidgetUtils { return false; } } + +/** + * Hook to get the widgets for a room and update when they change + * @param room the room to get widgets for + */ +export const useWidgets = (room: Room): IApp[] => { + const [apps, setApps] = useState(() => WidgetStore.instance.getApps(room.roomId)); + + const updateApps = useCallback(() => { + // Copy the array so that we always trigger a re-render, as some updates mutate the array of apps/settings + setApps([...WidgetStore.instance.getApps(room.roomId)]); + }, [room]); + + useEffect(updateApps, [room, updateApps]); + useEventEmitter(WidgetStore.instance, room.roomId, updateApps); + useEventEmitter(WidgetLayoutStore.instance, WidgetLayoutStore.emissionForRoom(room), updateApps); + + return apps; +}; diff --git a/test/components/views/right_panel/ExtensionsCard-test.tsx b/test/components/views/right_panel/ExtensionsCard-test.tsx new file mode 100644 index 00000000000..b34db13b7ae --- /dev/null +++ b/test/components/views/right_panel/ExtensionsCard-test.tsx @@ -0,0 +1,159 @@ +/* +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 from "react"; +import { mocked, Mocked } from "jest-mock"; +import { render, screen } from "@testing-library/react"; +import { MatrixClient, Room } from "matrix-js-sdk/src/matrix"; +import { MatrixWidgetType } from "matrix-widget-api"; +import userEvent from "@testing-library/user-event"; + +import ExtensionsCard from "../../../../src/components/views/right_panel/ExtensionsCard"; +import { stubClient } from "../../../test-utils"; +import { IApp } from "../../../../src/stores/WidgetStore"; +import WidgetUtils, { useWidgets } from "../../../../src/utils/WidgetUtils"; +import { WidgetLayoutStore } from "../../../../src/stores/widgets/WidgetLayoutStore"; +import { IntegrationManagers } from "../../../../src/integrations/IntegrationManagers"; + +jest.mock("../../../../src/utils/WidgetUtils"); + +describe("", () => { + let client: Mocked; + let room: Room; + + beforeEach(() => { + client = mocked(stubClient()); + room = new Room("!room:server", client, client.getSafeUserId()); + mocked(WidgetUtils.getWidgetName).mockImplementation((app) => app?.name ?? "No Name"); + }); + + it("should render empty state", () => { + mocked(useWidgets).mockReturnValue([]); + const { asFragment } = render(); + expect(screen.getByText("Boost productivity with more tools, widgets and bots")).toBeInTheDocument(); + expect(asFragment()).toMatchSnapshot(); + }); + + it("should render widgets", async () => { + mocked(useWidgets).mockReturnValue([ + { + id: "id", + roomId: room.roomId, + eventId: "$event1", + creatorUserId: client.getSafeUserId(), + type: MatrixWidgetType.Custom, + name: "Custom Widget", + url: "http://url1", + }, + { + id: "jitsi", + roomId: room.roomId, + eventId: "$event2", + creatorUserId: client.getSafeUserId(), + type: MatrixWidgetType.JitsiMeet, + name: "Jitsi", + url: "http://jitsi", + }, + ] satisfies IApp[]); + + const { asFragment } = render(); + expect(screen.getByText("Custom Widget")).toBeInTheDocument(); + expect(screen.getByText("Jitsi")).toBeInTheDocument(); + expect(asFragment()).toMatchSnapshot(); + }); + + it("should show context menu on widget row", async () => { + jest.spyOn(WidgetUtils, "canUserModifyWidgets").mockReturnValue(true); + mocked(useWidgets).mockReturnValue([ + { + id: "id", + roomId: room.roomId, + eventId: "$event1", + creatorUserId: client.getSafeUserId(), + type: MatrixWidgetType.Custom, + name: "Custom Widget", + url: "http://url1", + }, + ] satisfies IApp[]); + + const { container } = render(); + await userEvent.click(container.querySelector(".mx_ExtensionsCard_app_options")!); + expect(document.querySelector(".mx_IconizedContextMenu")).toMatchSnapshot(); + }); + + it("should show set room layout button", async () => { + jest.spyOn(WidgetLayoutStore.instance, "canCopyLayoutToRoom").mockReturnValue(true); + mocked(useWidgets).mockReturnValue([ + { + id: "id", + roomId: room.roomId, + eventId: "$event1", + creatorUserId: client.getSafeUserId(), + type: MatrixWidgetType.Custom, + name: "Custom Widget", + url: "http://url1", + }, + ] satisfies IApp[]); + + render(); + expect(screen.getByText("Set layout for everyone")).toBeInTheDocument(); + }); + + it("should show widget as pinned", async () => { + jest.spyOn(WidgetLayoutStore.instance, "isInContainer").mockReturnValue(true); + mocked(useWidgets).mockReturnValue([ + { + id: "id", + roomId: room.roomId, + eventId: "$event1", + creatorUserId: client.getSafeUserId(), + type: MatrixWidgetType.Custom, + name: "Custom Widget", + url: "http://url1", + }, + ] satisfies IApp[]); + + render(); + expect(screen.getByText("Custom Widget").closest(".mx_ExtensionsCard_Button_pinned")).toBeInTheDocument(); + }); + + it("should show cannot pin warning", async () => { + jest.spyOn(WidgetLayoutStore.instance, "isInContainer").mockReturnValue(false); + jest.spyOn(WidgetLayoutStore.instance, "canAddToContainer").mockReturnValue(false); + mocked(useWidgets).mockReturnValue([ + { + id: "id", + roomId: room.roomId, + eventId: "$event1", + creatorUserId: client.getSafeUserId(), + type: MatrixWidgetType.Custom, + name: "Custom Widget", + url: "http://url1", + }, + ] satisfies IApp[]); + + render(); + expect(screen.getByLabelText("You can only pin up to 3 widgets")).toBeInTheDocument(); + }); + + it("should should open integration manager on click", async () => { + jest.spyOn(IntegrationManagers.sharedInstance(), "hasManager").mockReturnValue(false); + const spy = jest.spyOn(IntegrationManagers.sharedInstance(), "openNoManagerDialog"); + render(); + await userEvent.click(screen.getByText("Add extensions")); + expect(spy).toHaveBeenCalled(); + }); +}); diff --git a/test/components/views/right_panel/RightPanelTabs-test.tsx b/test/components/views/right_panel/RightPanelTabs-test.tsx index dae7b1a79a5..4f702a46aef 100644 --- a/test/components/views/right_panel/RightPanelTabs-test.tsx +++ b/test/components/views/right_panel/RightPanelTabs-test.tsx @@ -38,8 +38,8 @@ describe("", () => { const { container } = render(); expect(container).toMatchSnapshot(); // Assert that the active tab is Info - expect(container.querySelectorAll("[aria-selected='true'").length).toEqual(1); - expect(container.querySelector("[aria-selected='true'")).toHaveAccessibleName("People"); + expect(container.querySelectorAll("[aria-selected='true']").length).toEqual(1); + expect(container.querySelector("[aria-selected='true']")).toHaveAccessibleName("People"); }); it("Renders nothing for some phases, eg: FilePanel", () => { diff --git a/test/components/views/right_panel/__snapshots__/ExtensionsCard-test.tsx.snap b/test/components/views/right_panel/__snapshots__/ExtensionsCard-test.tsx.snap new file mode 100644 index 00000000000..2cff7803ac9 --- /dev/null +++ b/test/components/views/right_panel/__snapshots__/ExtensionsCard-test.tsx.snap @@ -0,0 +1,194 @@ +// Jest Snapshot v1, https://goo.gl/fbAQLP + +exports[` should render empty state 1`] = ` + +
+
+ +
+
+
+
+

+ Boost productivity with more tools, widgets and bots +

+

+ Select “Add extensions” to browse and add extensions to this room +

+
+
+
+ +`; + +exports[` should render widgets 1`] = ` + +
+
+ +
+
+ @@ -113,6 +127,20 @@ exports[` Correct tab is active 1`] = ` Threads +
diff --git a/test/components/views/right_panel/__snapshots__/RoomSummaryCard-test.tsx.snap b/test/components/views/right_panel/__snapshots__/RoomSummaryCard-test.tsx.snap index e2bee3ac7cd..1986c2c0362 100644 --- a/test/components/views/right_panel/__snapshots__/RoomSummaryCard-test.tsx.snap +++ b/test/components/views/right_panel/__snapshots__/RoomSummaryCard-test.tsx.snap @@ -414,20 +414,6 @@ exports[` has button to edit topic 1`] = `
-
-

- Widgets -

- -
@@ -820,20 +806,6 @@ exports[` renders the room summary 1`] = ` -
-

- Widgets -

- -
@@ -1253,20 +1225,6 @@ exports[` renders the room topic in the summary 1`] = ` -
-

- Widgets -

- -