From 259bd618ab3700e2739add35e6a374e0926e7eb9 Mon Sep 17 00:00:00 2001 From: gradle-update-robot Date: Tue, 18 Nov 2025 00:35:23 +0000 Subject: [PATCH 001/113] Update Gradle Wrapper from 8.14.3 to 9.2.1 Signed-off-by: gradle-update-robot --- gradle/wrapper/gradle-wrapper.jar | Bin 43764 -> 45633 bytes gradle/wrapper/gradle-wrapper.properties | 4 ++-- gradlew | 5 +---- gradlew.bat | 3 +-- 4 files changed, 4 insertions(+), 8 deletions(-) diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 1b33c55baabb587c669f562ae36f953de2481846..f8e1ee3125fe0768e9a76ee977ac089eb657005e 100644 GIT binary patch delta 37442 zcmX6^V`E)y*G$_Ojn&w;ZQHhOYNtI^y0dB5x*u&jIU21Bhf}7%e`>rSh z1#LY&uAK}92G$A&y5+$IAt4F@2|8jt0LwA}}afFkG#WBw^#$TCX0J^k+I+tvA_2h1Itw`Li1kgyHcDwujll*+Po z$XwsbUNDm$Wt&2Li;oZ)KsqHBet>&OoWy>!E1MRems2?s$vd~r0vYTN=myB^=e|Ep zOPhp4yC7$yh?X{pJgiX}r=I+{B<4TOeoUksBm-D~H<`&WFHZHWL|{HK)gK&-S}>%I ziIqri>?=0OaJ^KsnnmZJiFiG_f?UADlLvkG)=-3Aw~z%^S?4XD<*iL~Me#4^m2$Zj`empiTmN1WnOgbi8v`sM08Y{O`ZL zDN>@uIp~1rj*c9p2a4rsJ73t%3fhNB|EHS9+$2cA79N(jr%Qb1IRH{_$pRXHaK`8dw#}-s*DfXJeoWNogcLPp( zC#5c477mpu8)E~nb*Lev%2hfE^f-7GM%lGk{TaOK^n$z$aidXt)|O&57^|vNL>i(A z#)k1{uik?cea-bP^a_f6K&sH6VAxcnmS1QMy#2JiyY`*r9k9U@c%6$#Db1g4QmPTw zP-deC)iPvGaxE1m;GFQI)sY#;1|iY~Z6?hbnLrJT6FpYiejmw@Q~IHbUGL-xND<2H z)p(|GQFxTZ0Z$`p7!szU_@vn|OEhF%W2}>S`xPL$Q5I20*Q2c#UZ*|-a{ zHzYc6en{$9^L)!5OqfHaa8Tcj#Y=((4}9UN>~bEB#cO1=P7B_!+=f+Q)*C&M+}T{A zC$+v;Z=?Rmh%t98yfbSSdXdE1ik=VA0XEuuTl;a7dqqhIalVtBiDWUu(_dP$jeCeT zg=taDEp4CPa+l{5z;DhDQH6y3?xR^7gTqNT18`DFf(ZXGMz10kuL(@XTIRo_Fi&weHNZ z{f+G(;f9?EH1rb4&On<@5auFNj4=O6plt+z2MsAQ z8k`XP$8pawNz0h;U|{P%{&AcJ)J=l{ibTZ&*eRe2A^E3#m#8U5L%z}D75eMWs?LvQ zEgL^DQ1p!?GLXUCrU=t9~vC@d(;hnKYq zz-NRPA}7GAe!c-G)@#XGGL2KR9#Pk!OP#C^T{%|z?md4$f^_9{Ph=PBs!J8(Tr9Gb zqDXW|?BjJhtGwDEHvYm1Ih5xBA!in0QB8q0A;={r;k1q_HtrI29(e6yr9m|ZS1p`> zw0xGJm>J`~n-4Ss_6bUB*oyI@{1V3ope$jB^p@#E&jhX?_o-ru6SU981 ze)V2H^*$Qu)80DEw0)aq15ULt$3JT0kL+Z3h%PZs68>Feuhj^a;WIF8F0SVWm^;Q? zF~#Eq@?K8P`}4hb-@v;B!!9{S5s__4MAlH1p2A^=x&k&ACPyA4ZKQAeD{#bKkGcWnJ&KdnWOzmd7*3E|K=Jp6|BnUXG#*K^`Fw zoKj0L0wF5~|G`d7z(qj&AMBdI|JPb@h{!++807z8x2}%nPj8A9?d4$A?55*L6-Y{M zXUK{)1o_*6noez=I8?gIK1*hAFLlJ-aK7O)?$HGxNK?lY({-_4^ik$E>|P<9pT;0( zO5uOyGQ~H|b&UV@wrx=JO?Dr$f1X0&3d3KCMt2*{T`gPX5rM7pEOwDm_6jGqN=sf1 z=?Va=;;1lVob8jLkNLM`xq;WsJ~%UHq#`E6{1#{)!e3H)|N2hrwAsh=7E@w{va{Ig z9)TaK$6`yQ+h2{`My4D0MBKs1#ilh=VJ!2}h#DO3B6=G5LMoO9*4jCysFxZB!7mT(pAs+&x3tA+WNE6*L{!uJLW%`O+he16V|(Lf61#p- z+5;bNlZSnyj%Dqaoyi0w?QR*Fk#Ur1kl&mIGa68}#o8sYOeM2va~cKbsjx*jCjs%% z>*9UbKz@piah<FraUf9bX;sb6pnTz6@^OtCl{Xm@FVPZ>AZLr+j` z+FrD-xpS`2$~Op!%w0nxbxz`5@s2qKdnKo~+szzy7VEK&ae-AdEdh0ef6)4EZH*CE z2u>zofc77JU*S)@8*;GBBkoF2Rsi_DGT1@yaEH8)D%3>|3K9fvf%Ld_`nJXrGTW~) zg*MA##_5?aBWzMxmgolOMBDOZS?BoZHsbWQonmqxCYPQUJp+sr&$;kg&PBf`=vTy8 zhfoZeUff7#bEav>zt9W`ClJ^wFQ24^$43&d9V0ii{yJYY)iTAqG0zpjiA*{Oss8tZS-9rG^AyY)Wa|1j~~6Bg#bIlf8RGXZ|*4fzu%?X zvR?7{(l6-$>Jz@e=jB$1Kce7C&Rq9D-~-2+e=Obn^mccoe}h`+X439@L@b#jV*SK{ ze2%A|pEo^H^2SWfxi+fEGW85~80T1ToZC5k$bGTL6zEv(S02%x{e!)y=Y=os5pyNg z&^ajEQY=aW=fD&lf+mfP@J+YWCi-FKJgT7~KUEbzu@^c)8O<)IjHRJX9v6e!R^;vL zKf?7J+_EYE00RR-{f}_t*s_3g1KdSyf5;SgT9D`nLZT&mCJt@8A+*|eR&+*d(?C|F zlOa_+cSJ@bcMBF4I3XKjhqa2%Rhp$G{ep5fyTZf7k(#R9zxmtifV__tfu1F5zo`p) zTSFD$?uo4XoaeiaWtY#p(Ki72Opq8vjb4{;$>ZuyIDRftxo9mN76AYO80`KVIH}Ees*qdW5YMA!`(*T zpVcITlyl$vfU=pG&Ace2Hf8~<9MtD-8TGIplWXoQ%lURZBQC?E55TFaRp!!jL1&huPF?kM)nXq0Y zSkHSGKvPF;8M#%Q^INbzNKOj^Ht0))l}6-h>;<+iJlujO!g4Oz8*9Ax2(HWy6_~($IN;e!=A3uP`^0TeU)dC{b&0=;1 z!JJ~urGMEwU4i57C5x--mNIl=z?o-bQNRYsKx@pW!%qQFPq%t{*vq zeJJvTX06{ea*@9AHC~`5JTcw=L3LZdL`~Hlk_@!wq$s}D=T9%4-iw}?4+w%M7?$;8Cyx``?!aOr=YFU+7<~{;UDH+XL_5(v4_nLN< z)_I+|aujQA+|t^af$2z1k<)Ltr0y;k7|_&Z^eN4y`Qz2UjId8mSsi2`5(?}9P$sGg z0r5}bTxpT2QLyehtu}`>8JBKi=f~g4i%>vE9IOD4TG4@QAu7h4P3dIDYh|B$EgOze zsSS6WwN9^IZ$r%UnN^T;LU};2)XyTeVQTuivote^uqe5hMpA_79W8;9TZqWtVJreT z4BO^Bm7_|xyfhOSm@GiLzrR%pa*2L*kv0O54UUx7Fn*rXRt{*LZw16Vc12XMO9F~D)uL+OW8>IOoiV`6Y;;N{kQCzW0Cs!IhS9sdtxUG`*{jq%{>mF?p z0@OH+uj=)nafI->pI-+}=<5n7Iu>x4v_Y1hIY)5@QW-_H~dmPzJ z)H_p4ln&SI4x@~n+X5Spsr|&rrb#u@3G$D`4LTW#DQ<5Laiy(Bl7Fc2K9L*0|*znNkRynffSJJ zaLio&qPSBb&5zn4KmfCqs{npIO%Xag3T=$j&CzO8;)?whCQ^5QEQ49=g3MNz191T} zxw{4Ax`3ND0+{}Uvi5V~e4yX4;*KWadQGL&>-%b*p?#VrzQfPh7M1De)wWPXkDOE< z<>dw*-_FE{xeksr)(k&G@#03M00EE{1Xe8(!$K@`3Kw3SG{k# z8vPRB(Wuj^NplhePT4~dxYa~+XrGAaduyYUo%dK-flcB0nwH<{aEM^+R>4ER=X_>A z$Y?8i)rKB)Zd^VW`2MtTX6N=Kx3i^b$p2g2tKsdZRY)zQ!B^y|{Xu%vs16u?7FAb~ zBB9CzBU3N4a>TyeCmN#A_Umev6)#nQtavE@X26q2 z_9Oe|_|Q9W>`VMGOr3cnE|TmaPnJp|CK3Z3IMxm)^P6(eCN$3R$pmm=BwS59Iz}uv zh_mtStIzK%Ftx!DCZT z!^$DGi3F5DL<#6Oe5vjJD!7%madOcZX=*A+$Ezwx&snd>!(Yo`)vci$xrURt5u6#O zM})7Znb^#`hFp^l;|VOYbF>5#6*hzoihwWZK-(oJj)DuE8LW8K#K_jM&fmXnd@$DvXp$|uvQ5SWGu3evwGe;}6=DxC~ z%0WCxF#rGyE#~l!R37!(AUsGbsD-yE2a@_oab%Bnib>Y%j^Q;M`Htj!&Tq}e{dzRr zqSqTzA)i=iD}MX4FXRtLUG&tt_(3vVB`18$0%99@E(Lo}=a+Sx!V2#WMyCwc7(a~> z#X&b(F(wB^mc5IxiQzw!@pJn_HS<+QX|WqPet>4O_tcI<=n2Jp^tSeBcUHKD%sf8~ zF70vG3=vopQ<@OR-w~%JMfbl2Y+QN+$OL>4+v#))Rc~ZIV-=^aXz{u-*Ze9;e z`972;UHl970lJr;^8FfV`1@8xK@vbJj?g~%AeT){G5Icv-VJVLv!Q*1S|S9eor z63+tjSKkF$#(#l8`}_Oz1Iec}U)hOf$U9fgcF|3JOtKQtR@{*JVZv=_Q8y1G1CrV_ z;UbSJBv>Mzg_?FXxw$0vI>I0n8v@PELOierQ z%bQydx@H{$rh*{`g$aivh@OJD1Q*hL(-pN2F*Fp8C7a|3%4JKur z8~}a&?K8ZzZEuVXNrdzBa$LPi0+=E&vzKF5XCUd-U_0sm}a_&jn+{ML;Z+ymwj*kl7 zNz~0NC;lg(m@`Nf`j@x^Ygb}mkP}c`#4`%RqkJq@^Ibc|EFPTvmNy!v!*Ir$ou^(z zi3aM3T9O5RGkx?76|+|sYd#MZmVQpn!tzmWH8C608FWl1n)cQ#E$ z^o{Y(q2!V5@-H%J$V7ju?jC$qAY22*^vo;5C#skwW*b9#oMdHemvlkrF)m`)3`0L} z6~e>gHYGkvxv)NoQZ6rN7LV956%gfE(l)!`k!PrBimCAtb-vYzS6INMOhL9RG9t(&o~J9n!|)&CvH1@Mm;M1>8sdLD3k8J)Ku!UN2?-CxAUTgjX{XTn zo0AlMTzG^CLbW_bwNW`q75uPgay8plwqq;#GA6#_PUHnMi~6w#@g%N-TRwOWrvlMG z=h-~R;%NCg7ZGeGa2fu}-hrWQy8{OCxQzIE0j_i_5VJ&zoV1x(%|B6GvO_##gD`@{ z{@oF{yKxW!xRo!}{l$CpXGOvDD5_YZbl$#sTdDere@VfGDuR*aia;ft8Ut1d4jr{! z(C&m`uRV++Oi!RM^w|#;EBK6Z(k(nUL=^H;by(=P7bz2TF|@Z;q9gj_=qb%I-4Mwc$Q2Wa$B|9 z=b$yl$f69Gt8A*=bYds@q+dUP#7&f*S zW1yL4(`L;Cy&uyP;N+hO4oV@J30ZaU6;3z0+*f(8CQ z>^*JS?keN4b1I)v7y>{ABuyn3@jre(q%?~nIvhj+$JeSx=Qr16kQY zE6)A{LPNEPi6=@XO(Ow2pI3zYK^z+%uK2FuCrVq+&|V;r)Cjn!E>!B{Vc+8e)#Xmyg~^hI_pn#+Ufw|~`h3XRP&l3)ZoX%&RTB}Iw( zip3J`t!lNMH_x2d5YQ^!?ibq{!*WnzLFo&*hgKo*la)~f+EPtEVH`88kfMlj ztlEh!kI-^CPhjku@SUpV;Sjgz7*5g%Drwy?D#wYDV>0~Sz$)O%Io)vcRKkAZt$GA& z(!6kXr9gY$dwUyCQYxZocyk-AATmUlRah(uuRy8{^H3)fz^-E-E^_P+ixsRafhZdg zCQKaM#-4zQjW7N1ovOnRZ&)|fjyT&Hl=u2*&P}CI2MvO!PW2t(8&x~Veo4hD5~F0K zd`FiqYKM1TTm!t)%J#a#L@F9HYVlQMrxH4RNKe%GktRtg{B=ixSFgBK(5Gk&+b-8* zq_lagx-ypCOv}C`sJVxHcP__+WYNa6dEByg*huh)1W2ei{8e_&6V4dm=fes1%H+f! z;LiYTq)L)Z&X-+ifSFTBoWqL2nPRWL50OmpYIYhQu5u=H$h#YprdCZDx(yKKmbow@ zt_CBIu8C=mRip@TC)KBYM$6mBF2Rg+{?7;NNZZ>i|5pX3{#ONt=!^lHQnZHuECfs2 zo^WGA@+0@>KeQJTE*??8ND%i}UPM4a5dywo1Y?}-XjZjS{khq#EYDe7EcMUNxw+k7 zw1zpmI|x%3)6mv@aYKMLe2JaTog27Myb}0(jb(IjiRd!-w#;i^Y3vB^GWGK7ROVu z?&0ibE;~*)!LN_WCG14BoBm0_6u$8ly$M54&fh&6KfyQdK#etU2tPMMJz|(gKow1? z=ty-pg!Ygxa7T^>Nr%jT*c;jKtNKRRS|D}1r1l!Q7=C#m%#kc(*q0tKD`f5)SG|CT z3=1)zHl{du?gV)Gy|({TrPVP%-QGl2q&TGveN;gP3f_dG7$^Voghu%;PK^gT6@6mQ zUBG_#XTM|^oYg@AV1P9uPw(B^P62Dz*{}4FGfF@ZP zD~4I7G)!PTYy&L?rNa~=m+9ny>2=t@E1Wejmzy- zi?Mn|#uVNpt1>!31>LkcguaE&vTousNf~3TL$7k>wwJ4Vy?{rbu9&(bV~#iW^K)x! zt3IR=lKp9V(KQ?1J-t+ZUKNXM5~*)48bu2;#B5&6l;Gs_99y#7nCO!cd(g^yAwajs9RF$_-|skMcGTm*bild?wpt#1@WH=LTLF)B4WUW79mE}> z!}{ZA24(;aQ6j=FSQ0a6Lf}w1vjHaX`7W+*xjQpUa`oI?G(YD!qDVvEQvbx{vpF5_EqhcTGPfyJ@@8$}7Mov@^N4un=9?j=llt}$ zzMcwylO`K#(!FcMKHE^)gI>Ee!YZ9X7J`ncX2}MS#xc4v+CxeoDkap;kkhhIo# zA>4oiWsYGL{l+Kjv6CsSYDmvEeTt%ZQbQkdq@!B!ZHe%Uv%YwwyYEL#?%5@ZEv>54tD#iB`QII+H>YWoMg!R>C!+2TBTtsGhQ z!^%SvbO+$ZbPMl6B=Wz&w9Q-wYenN)6Ruk?XWj?GQD}GfYm8Q-b_VyRT1G%<+|07* z#z7Qz(qMT4AL1n2hFoYyc*XWPzCHO~PA`vO1a}Kl$3hzS3cGT?!je>Cz1ac6_?pA~ zjK}%aXk$G(`!3Zs{9w9*<}{b5XRvejJQKy$fZMaVB*V&^G>-Os25*&bKF)pw7$;sZ zbK91Nwg`S(p^``bdBtW3bSo73LVcvQKy&bp2y!LoxsI5SP>vzukN$xtI;s1CdB&YO zs85Lh#wG@8ddf3!Ft9mjFi;_zB0xt2M-A=sCyXrCce}Z{IdxJwnLyoe-2unS@5)wE zdF+j87z`rLD3IhVPUd~qspIsiUwxl}T}?Jb4d&&3cfE%MH?z6B!9#xJFmkdf8DU&L zPZ#6O)1OaM3;@3`k^n0-tQ=l{Uy4sNM~Tr37e1UUICJM-Nk$X2$cmDc3P8RDoOlXo z>)@9LtvrDTI!(svVY*+XYHg4Umsq_gspf0&2iu@MDS#tO)|Sf8q_mQg*Oj9w{OJ{xHY|B;F{RkX_kZK}Z+Huo zSff$(#+3}?OY-DBUJ--Y1B~U%$qKJZt;qGhi35oJ01JhQzb_)|swoq`<$_y9Ck{6{ z%yNfH!i^yo%Rv>DPi{b$LObHPO%unM*vi`{m9n2kP1_REE8@WGnrnj1jfNgb;{|a?Jviy}~N=2J5vH zFTCqWVAt@@M}g^zuhjGwvud`{p9E4F9tP^k z-Cn%iLTPpDbfcmEhLCj2#-lMd4Kq{RkzobK!6D)%DqVD_e&KbW7eI7jQ%kt@zzjRB)p*2oKD7J=BREc*SoSoH z_6NQ?fw^bQ3}B%&(7K{$q?Qe327xF3kn4Lq-ZLS^$R=cGy`{UEV;O5CO+zKNw+j0Q z-b_X-jpsK4H<5xbI1Z@>d&#?q(7mj!HL3Hyx;(z9`G<|t=Hr7!spI8cMea_&Xcn`F zQq*Bi%+H@c%yiN2$P%G&4)U4l;kYF47D=MX`xuy}ZUA%`QfdEu-BV`sxlxl2mk=-J zm2hh912wx~g_XCg@Y77_`~HE-?L4=y9anG-H>4G6dsLR}O(^!JE>5Ns5hhKGR~ zo!T16FC6M&F$-qZA#3jsERGF01}6{^cDYeT3tD-pEN>w0T@8VeOH|||fHI`kQ&nua zZ+@&MA3);!Z~;D!9ykb<8lrX-P;NNm1*$#i_zL{?SKdXbpG6_{w1h<*<|ot3cb)UF z7HNsSfAJ&IcK?8+tu4n;63C5l<~W0N@(%K-RUKyjg`lcbY4npWa8<>hL0cC0)1)`NlM1EV zj+bX*Nzn+rq1m27^S$Tp@)dltilf0G(5kJ^1v2@6p{@eP=SM}*1&;~9#${d{jSnYN zlIf^8#K?Ua1{?Su_ZRWOCJYf6nEx>q zXY5S|go#sSNzpjo^0{hlx7hCRdqoU@&^5ubwcD%~a9Z-bQ7p2v7=_`U`i*KT#SqyV z`==qr)J~`ct!_tJv34AwMt2gqlYd4rrge6s8KG5*xrDM+DF!jz*SE2;L3}v&_wBE| zKrD=+o<5IME-^x(Dl~R6QU19w^_iIGX6Ex*W0R&wPKF_TvieeLU<=k@P=3nj3?iAs za9^A(F-wx$n&@VlL1QhtS}!~xr~ zmvF~$Y38~WU3Qdq&MWTU@Jl@NygoxwYqrxB659R=dYmAP8aU(z3_I26@6(Plf8jqk$=f1 zlpk!s&HNb-vn5nz2lZW(-`^1hI;OAADW5X6dQ6NAW6fV12MyT-V(2tRLraGk;|L;@ zEGBJ5Mj%&h-(>kGwsvJJ%1oGYZ6Z`1M6Gz%70K1HvMv_@<4&}~_y+Mt0?6h1ez@WK z_I5ukush17*vurxm_n^HW8eB$X?#z!~>!3#?01=G_b z!q@Uc_oWZiU#(ZU5%y%#Bz{kT-?uvGn71+z$Bq&C8+q#kwWYDA95HX=AcNOU(GmBsVS~qjwA@$%cMxuayqGV*WIx%}Git%fH}J=;B>d9(%Rkh` zW4y*_!!Bhb#cg*0?l=GNAwa4Zx_ZtB?QpaZ6<&^1I}XI|Ot|V9(vaeaV-^CTPJJiy z_3ghosr4R#0OemGrseP+;)_8t(IAs|FGk)$IfXx0WA@v+5 zNbEOG+^r|;FFy0C%=fC?e~G;vOlJPQB-;wQgn4!|SFtG?Hk{yMxgtIjm zOO}l`J*+$>D`)O$>-mccuycD=&1-B1%nn1g@qwSfz%zTX6{~=Jy!EW8CzE@ww#J7< zkEKLL%JV@Va2Q`uP%R`gN^Wbz>}{DVeS(I^+ep0h=#MEsE}$C}ywtw$dX08Fkw-N* z!a$zfus&)9mxb+n=GK4P4!WMYfn#_0C4}i0()>`U<8AZuWA}!J<_gwV{B08<*bXDK zWw=HUBSiCU@*C1O6ZobK^(uk?9&PfOh$!oyqD1~bMae@*7ND&6FR6;gM-n>thY)t~ z8gVJLKu_Iyp9iV1vp+j)|IxXevP(3G=g<$=u0IF|@~>!UppN+PpCcMVuu8bym!g^u}vves#PwQPOv?)_<7{9{m@eQ8^=||smzq1 zChZ?VJB{8D-=N5K) ziK%|Y#IHsCgP3dV&h&w-bgG}Q-=mIBJz z^gHVwb+#J3wqqJ$&_D=J?gkv-8v-U!Vu9%v)ap;Ig5~dsA6;;m_hJ)9LOaHyO`|TC z^|Oa}Yum1vQ7u`Znk==ys~N#&^fxkFvQ(;i=vR^^dcS2^H6X6Owr5)M&&84)MGV)- zZG(^1`K>G#2I)4Yq&&c3GkrV1-^-0NSn8BGnCYM*`uzHN7w2b`lG?);tDhG@wbiLI z(Wt$SsNiT7Qp}*qEmr=R$K2P5x`DfU<#g!zTkr7e`+x^V{e%$#SB6DPK>7b#+4-E3 z&)UBiAO82^IsiV0f3ajg8U86Ok-ZSo8GJPNgL|r>P$?t`NmU_9%>qGI(Bn(T)aI6z zhg~G)E73dTuV3+$FW=rN2VTB^C(Xc{%zWPJ*!=k1Kj#1w+0b}#bbIu6Mb1s&x8RA0 zGvSNzsiTh?J3y1Q0u^M{?!>x~PcvsFC_F?zwi=-E^8<2}uUauRw3HQ-)7DHlap583 zLeIs!ALqq#;C3vMaHYoCSyEQ9Ghy0HkIhnd3O@@!DbsJ5yKDuiSceb$to)6f)lX9B zWmqIYS@X}a6_I*>f71pd&UKKQ3w^r6e7h);}z+X1Rseme(2-mdI-4 zq(mk+TLOq#(b#jbZ2D9}8|9zn;N&)}iG^h#i`X=Tc7=`~96m-*bMf|T+a{%+tNMD~ zMo3FTlS`eYzHamY^3{Qt0AoEF;tNVq2#9>|(9WqZS)G=sPIC9Un%Ym@Ei^k@NzTyB zyHt)MX>G1+spXW4B70o_-b)2Rgw5Win%jTn8?#8fGyBN`*Y`I}1<>>c^*>6^UDVBh z0>qpFat{BgZIC|ox9%WLQlKEXeN)I9c`Q*;@4$?(NCK{`${^*4G8y+OUJZxVb=%u6 zq1xdb4wSs^4%l!`LIzT!^14dG3&r~n`G#v+#W`4{_PLI0-usCTg6WBQ%`aCjKkTQSybb^_`mN_WK{tXe|3c&#JiN4-ct-X>Ck|GO z^$mo<=-K*ly)7D^QSAGB7Z(?c2pm;|Ylq=#8Nrp^Llsu^oJ&t(@K_7fHB2GNI_R3I zoSdo@x>*i?T=0LFB>uQ*dw=#}ff)oV=sY_qG}JoZt{+7eTMrz(s;8?=QbjX|?H>T% zpK?3vfzbUxRPjF4z(`gR_uyx*!NVLqEv;=N^CIH_qn<}Q9dLM1Of$G8X%rh!C`#M# zJ{*PXi+wN5Tv!6{0;1sh#p#7XLNP&qpyw=UnrqmlU>Z9XV+*9{6hov&S$&Ent{xnz zgcm$wnrA2*28=68ozFLs^oGKAUIJ8FPKHZ3wJhZGLq`cw(K28zL((_I`@;7-thpvj z;Gs)Us-|uyEqHfoE+-5R|B5x1-is~W2c_Pdd|5gDoAE0+r}Ca!aiWsh$&|`4alVch zT+tL4Zm6W;!?v{QBeBn7MR}#)OpT_wRApz-wuk#z#OxdbqF^#>+Jk~73IGN9(IB*< z+6VllEYoarEE%j=gYp_*w|O+aS3*_aA;*`=rNxz~tm>6|f1r`EgZ(mhV0UuXhjLZ@ zuL@1lDhntl`C%g5B}u|Lo=#DRP^0h%CXSlBEwZE-r3j#@^*!aaO7VMGXUB+R-zuw^2bY)3xT>Ar>2-6<#w{X(xe2*QXRws{a_zG z3a=BJP%qUFa6fs4Xe!OB%GY1lKRL-cu8Zt1`c?*A)mL3j$C!)nsT-vajWNDVluwKhwb?1v~o?)z-U;qYd< zqq7xcYL|=^oP+sGIq&4Z|FcoGsaz6d{>>;T|8IbcN{Ik;{%d!i!0$RKVzAWE`ZMTm zI+m5;+KR|!9)w8rLqkw3wqfo@?K&3CgiLoLzBjWLY}y5+LlkoV+*2+35<1ekqIQ;J z-{Y+7tXFfu$LC*!9zt^LEnC}(68+Pt4P9h;b%LcyvQ7hzP2t%;tq!g79XsX_tHret z&){758-S=xFQaPD;-FGQhJW`IAKpxu3^&FbYg0^|oQ#Z&qMGSzQ3lkj?ART=aR&KS zj?O70Aq`o$S{k7bWf-d}5tR|Dyfo^M%SMclZc}tpDjUtVz44A_^ywg8o2Y|~gTaFM z(e|qhlXl*99+J(}a}zQF2Hb7t)@x~qM|iw(UqCVi-Y$iWZwx%L!{)tMATbrl0VXcr z%^Anwj*f?GFp2~FmxEU9VH{%v4qMj=Dli_|uRtiYL|7;a$e58a6QB;P&bqN^Ij(AD z)=|n>Gv#y;rTDt##u7~?NitIJpoEEop02^P`Yvu}s3y{>Hj?=(c2BeClvCu|h#1Y4 z8NfO*Aulk=sLN}cK<~=23ofsoP|Tv2MrJ2QJ(?JLQ|d%cxY(bk=8cwRV)+x2TyL9A zFLQTAzjiWP*LeytNf>6TP$M)J4nDha>o(EM0wVi@3>{MYree+5i4(B=hNV*04u-sTMf32#Ox*zVWIp6Sf(ZRTL6T(|0GcqK zx@zd34lJN&Zait0;?Qr}x%q*viRn~!y{twy^K_;}u8Ar6gMXP_SiCMLeENMH{sgG% zDk|wB2?>fhRZ?13x(Y|oQa41xQI}CtQ(wIWMM6XzZ*hR+6YHMl{a=r|T(0RoeVp#QR>C|4pV7Z`XWv;jxAq*0g&Z2IX|V1 zi(B#LpT2zYwi%ev_SO!JGwP-H(~PrlV?pgUHN;eCg|)`Eu2(1Tw@bXPD9DqMZ%T07 zYGP*h$fECeYNZ07sv%e0a$5D~FT?y}pMI51M6b$i@{nDKjpB-M#hA51W=Gp1&c0Q3 zY&Gi(Y9~qQY@Z%+s@zdl1#n}@%WIK)4a!X@&n#%>@1BUR-@!haZ(`piEl(O#Lnp{g zvB>s!2IQAGy)F^T_Z5I)7&G-tExOWhh6){)*u;@>VrwpIwqn<<1#zO6LLd#D!c)j* zD%U2NBBZXj*(AtdDu6C2Z>0i(snh-Aiql9Ld^LvH!NMcwyM@&afWLQyQv+J}GXdg| zxm2qZ$!;2i0jv@;q)Tipv{^@QW;g>8Xagez*jMg%b%g5SjZRr|?Ct7(=r392%lnC2 zYMOWfK`xeb5e|#>5cmT$ybyHrJtq;AmSpqy!~=9O^$6LM<=z?hj$PsCgZ5_oOgFj^ z2zcYous)bj`NmhefR{S@a6)+`gLCY)PsB2sm66&9%_C3Bb=)3uS8(JW-Z~o#qta+ZL({y>ti(OS zf;^L(wV#n3tpeA<^OJ^UStdx1#C4_*P6&nIy?y&sx}4avV#DTdyCb~1I0lZ|%b?Z& zk}{dM{XGHBqD{kb(2Ou=d8_uOd>11era6+6E{Ne)+iy71*4A&vt4_d2_X3X8#VvA} z>X7^uOi6|R1Nc!Z2x0dbe|}`*h5XO@P044WE|pbb#SE-GGD6c( z8ASh^J%&(i6pjaX$?}czY}%%bo^7gZbBjwKr>D^qPpye+cnZnyhn~q#4;d~|i$fr{2ck3c{~y}K1{5X=^j6_#YOvcazJYUMj|)!8jtC3SIOyb9PxLj z@A{igCn(aDo;-T|Ed4FjhNknxliS!mF?$(h=)&YeyxL?(^-*S0IepHkTXd=$vaee! z{uiOw$Z!tm0>_@^q_)?LP*sFm=f!hxSntd&)K`R=FUb&RVptez{m`431OwUM8g@nC zm+f@givgvD7NDi;nUb}mt}cB!Z|%%0>&XHh&3U;=M!cMYxuW8d4w{=>dLnTWB0G?4 zSxQNUCC(3sI`Wdov1+MsE=W9C8d1(j>&eNl9+52p?E9(~^e z6yJHmyd8UKawp1h_Uc3nk(1*SA5@iUCUo|0`?s=Xs$D*nhWOYUaC=qo$TG3}uPqmhDit zieQL4M$(LboP*N~^g%lx5H(XCF5K)!4+Yd~P1AGg<=aQWTF!g~-*s%-sD}RV7pyYMNovcnSOQ>|*vFN>Agd8o0CXq?TK7}d#+ZQhvFE?g zIKP3pDgMH=IyK;>|c8K1>S{u}9ry>D} zHS}FhF>Rc479J{bOs|k>)hYL4;!BpbN2bu8P(#rzBMXA{3c1) zFY|yC?0`Zvp;W7w-;~Q9OBqgMnMtbS`+p>zV{oQjvxVb{?M!Ujwr$(C^CX$rwrx8T z+qP}nXWsApxT~wW_OD%aSM6Ti>uS7Iig(Z)a`dN{wlb4lXeJHJHkt&$X1(!m>rD8( zt~Vey83W~pM$6wA;_!LaW5AE7j%R*h0Oxw}@Px-H5vW!jj)3o?S%pEb><(z^Y76$45CfLyHnTAG=56F)j`<`-wQ| zO4w5{-JNFm81s!NJlPd|lr>khu4zq!vpqL>ic_E>4JV!Y?a z`Iac9B#Y3+Axn<~K)lKE?PFL(c@H8z+8Y2NPq(>&fG_Y;|n!3l{w(-O2lR}|>4OcGZC54ViSB@{m(mC_6yXuweO zIAG(V1^`ufo6C!{=9j%8Uncx=(*%#|H}?P32S!^6u2m=?pkw6! zH&vh}zH*}_s(4`}&XhtVI;ar=6cKq-LALzzG!zv+bCf|)WEiJ@!d1* zA3-gnDe9i!wy;kxI?&$ZFUAJpKnDH!U8^j#XN8SO$0$z;O7xBig zOiY_qVugyeEBH<|R^R&wN;Ad;cv1&^ov0jk0!5p>hAuKx$9hrh)(BRz110s}YJU(Z z+y+!Mn-084>aeLsT#}l2ne?f#M2jZ3Ca;Eyo`rJP4LPI=c}l>K5sox6a$tWu|Ln$9 zk;G~S6kjb*tJQuL^lSju*6mu~yX-0#{`oYQk;|F@%pGGQYsA2|3-_D7vUo6u71s3N z=s$8^2^~4IRIv@cmu4y2!<ZRwjN#LUhIGy)wO&Be{lZk`&{%XV&(*3~WOWOFL@IO}{B z)mzrSTd6DN)mxV(ML*8hG6|Ao5`b9!$8GQF7vGbO)PEZB?WnOxlT>@o*)@*+X8W@% z+LhQLAT0g#-@8eKi@JiENbN5@$FW8$`%X#$e7GK(1#fVLq)w^>)Rkl1V)Pa2z-*Q~*<@pID} z(2O}3Bqdi;zJenjy`C0-TCuh5*M%ind1&S|TtCB7=mfAZ>7k`f)97(QSV)Rr3Q3EX zDlcMAc1=ISm86CvGN_+xuvAf@Yql(!lpw>BeOZnP*1RD^kex42B4eKF;i!^QPAA&~ z@SVXf%=qDp^7(Q;vpIg|U#KCX#0`EHrnzhX`1pzqw>c zHm36wx~pVN97<_-y0gU!TSKh-Xyq;N++!55R;u)=1Tt^z5<7-5^2Ty$ZQyB%M7nB8 zqz+JJGt`JBgR3>}sb~!!ve}RJj--tPsD+KEI{eP~5LA@~N~tOWs%_*7)T;9|I|n4( z2f`-Oe;Yu4D{E4S=#|Xf8rYKR<}W~N4ISe4)XrPgCAHYZ{$7R=7=*4{neR~25*Bn& z9-LC?pt^x`YF|poS+;PqYhVhGDKVLss%T=YUHq+?Tw|ydOdJS`u=KAU0U}lhh@#9r z4l{OOxmhBx&XHxGTQu4x;)>176!9+7KrYUyWm;4svGbxftY`^53QRqTImL@@?D4Yl zO2Wh^$7E1O>w$JBn8{BfBBjd+7F$PVX$K`5;mwM52Cca<)3&n^DP?s9j#*z>)DIy+ z-_P=Ck-I%JzlocMOVC7kgpEW4M8qNAARsAG-gzNo%bLz`=g+vfV2!cr(_C%b_a*wd zQdYN#3&80{9BSPnl7LD;^>wjb`%l^K1R$C~w$y%4Z@^V+^16jpQ)cK1p*Wl7LPYDx zi-WP(M~)i^R|X~Wh&527ghIPLJ@;aj1`i+7$6e;*NR1Ydr1c0AV@|pPgvqQ*Sh*sS z#iC;d2Ftfq)}wv}<+FOxE|^G?CB_U}3D2P_om>#AWTroF_8 zYgw#2tUd#VJ!)6C5N~*`2APiMv7_w

WNp5~7YD4``2J+2^JLXSDAn1#GQa=Wm~d2R({ zo63@NZ(FrJihQ9_^uk{wU5VSIS%+H(kcQgDKY>6>gbwAJ$%XB-?=Ouo$MLDV2g7VW5&SW870b@!rgWBdQKt`zM07NLOKQp@?CQMZO|HcU$9EA* z->CPr3Vl_okGT}K`MjU<&vtNB)pwSA{El?B2M;YWFt88v(*UK8Ts#p?snMhU`{W09 z1m74uWQW|)p5bV~wi^mL>B5FHo*oORQ^rwD$jctPfj+8eybIwzYXmcE#Fkx zD6{ee4_e_MmM^+SP#&s^wt~j)S#dVYWjdw zA-bFr`}0RsUzkOzS~=ROGiTu`rs(c}s1X$0wUkA)XWdqvw&wtlejT0s%>Dpyod_a(owhK3$j-yt`FYiO8p`$LWb% z_y@R>D?Bm4L4n|tYDY)P@BBWko$iR8>q{+ZdOj>!qA*g{mf4&4k$WyWyXeO_gHtW( zU4~_u@ciaR(FYL-Fnb0*m(eErkRuQPhl&OOVTyZ{e>4}|rys?)oY;Pxl`e?)4ETmH z&KDQZnyg$A{>l3lWcE$j4A1&JILYD_nri#d4I&3H!jzfcV#4W-69y`x8vd@m`2!!WORtD*v)GwkwKyjP|Z5`>7Y9On%F3{OYDcg91!JG!(G zIaUI=|J~LL5q%;XM=OeY2a@jti&?}N0xd3YW;2j3J%Yjp2F{s@!T9@t#Q4zRkBTm= zZ;HDMI9l@W^h9dU@@Z$R!jZ$AqV&KM*q1-Xkv$Y`cs0iYP^gi>A`_v3p{bD^ZQ1H! zpK(?ZFGb$GKH#6RzENZS=@H$_j|^r|^>tR3WC2RyShvH6OwLZRkW4`AEdkiN3-Q#P1 z=*yj7_J9x2ltKK1keYfb$1azm%kvuG6LX9_nfYn-TCU31vPRLRnUQcSjZ^ODv>5LUx$J`!l4J^@`&gh zLBMK+7^x{1I?g+kU5}}nJSQkO><^ff!dpX&&PPO7k`gTqy*^8U0nQ zpdycJ)|i@z5sv6Ni)L`w392E$COm{Gu{JZzH|`l z&_+G<=yYky9O+!d{FO-FEqS7id9c_Q$>f7%jJid$OX@za?b02-6MGi!w5+VD&Tr>jA-dJQ2MJ~r;?%;fU3~qz?d_LtLT659>X;n1NTrNe`*q1e z8l8Zc>P$^0r#xiopNnu8>iSJ!4DEEa-Aq}hX3Y5NZ{usP<*^fG#PR}I@qRt{gvtj) zRdz2a1?9v?rFvP3)Ow=qmY@A}>7Fj=ys4>!;FOfma1y%|@6fl97ycYbf>V5m| zMwLm5wR-Wu#ot>h`r;z@*HjcHSck#2>Fqok)oOWwD7W+#Y1L?C`bs+!+s*Pbm@)1? zCj!5ba0cYQc@7WfBk~!ro_fiOb4~rcu8stCd?!JZ7=f3}-t8I>sj_NBk|!GU6f)P1 z5$rz}gw$w%Y@~Jwxv09qLdf;_1IDijQu>L#uo(_&HwT@}XiGwmEfbuhMnmGX7;%j@ z71Dy%o&VtJH~tLm8T{v6k-`7?+VwT_lQvt$4??UuTr|ew6ITPk>{kS8{5Q16{KR(> zzgW@bP0|Hf4f$#W;mQ>jw^5wpdXi**G_i0!4BuGHs*b51ehphBfsAK*hxlgw6W7z~ zTaNk+!|DYF^p$nEjS*aDrMa|9gUoh4<*WR!%3Y{700b$%x<+RxB!1zAfBR z#xAW{SQWJ>L1mJ~Tf}V@+F_`?&1ERR?ZMX`;12Iqv zdWcbf7)&*wNVIs3|M*^)Qr)a~Cn^1HkNHJABq{@O9OJR{b&$87|7AmLv~Uuw2SB4T zNWw%meUAwfryJVYrpUdYW2fV=uDyH2R4kUryI#z48=`m7|?b?2XrH$kwRG zV5N%`;e2&$y~B80j!PL58XPMv?yH}zIZH}w7VA(x)@cn0kON{Z7#FtC!8%GH1HKL* zqsY=(xQDVWs%3$jRwxCtrIMe(+0la)DjI+#nKC%6a0NlM)J@{DUai^LP;~;+Fn90~*mXvc%=gWPWbUN4V|Pya2t-?`l`>uQ?GvPnWYtdd(~?r9#TI z)XmX)ic@0`+Jao7zsDyerjhee$AW7SMsXLRLtR}ZL4)*BqI9KVTQwBbryxmJGR=N% zn6KBj_{;^CKx3EuI+b4`lM3HWq>+M%i;Mu2zlkpmW$$O)8>g>xX35_}V z@1Q;_W6%VS6fOn{vV*yxvsg&}OF`4b`;&xpKxO=+J6UxbzmaR&6(W~?|G--d(+YsH z>4|K9_)hV@C2}J-@^+ihBea%l$i8C~bTlcR7?Z#a3Ug80QFS3Byfss@JrMPVNHs-i z5X15{HkqzKGW1SOswml8S2H7__?~8JY~FNFAtl8l)vWwE>D^`tNcW9_&`-$saEn{Q zbuXoYhV^+N<$SiG;`4>=bLD(%ZwruK%=?8pJrDdr&myrBjPTpyihRH`L}sN>1r472 zudc0}eG{#;qx}+=)R8)~1}~Y~%dxsw{XJJb@^d$^|2BJ0K0Dm(2Ex z8Ly_7KL6I1JU(U-Lhzp&|Cu%U7e1L>6X*`#>(H}CnbOy+8PaWeW?uMtK~{h?XzA+# z-_l1IVqyv0Jcd8D!pt*V_Q*R%<72Y&A!r8l5zm=2g6Wx0N)A-Vd&u?3xBH=A^lEMg zp)|h+Ezkt;dlj74wG&>7y}a2OImj7ioF7^IC&(Bl$hqm(;f&R8^BhaTc)a7;I zyx_ZSTkiLZ4UmODtX154sVU&>O_@b^7Wu|=y9C0i=?^JLg@{ns*a>zKMt^sL@HWQB zS*+%}b;>v0^R)0O&DRBL@)3CRTH7rvJ|7*JZq1Tb`>}Fk)u#7e)QoBkCjyM*1S_SL zLZV4CNCO))Mj+6gr6A%d4i^k}dhnzkVyOt(A@wf>dWMEe{{>o-=i;O(=VVK6hCiXkC%zTs)@~%nNLfA{5 z9OhQ-U!J+lzY)dNJUfGORy$uC0zI^P^esFW+G1ON!$IQ0s1$vkILM3{kuPfwQn5 zbkf~3@HS`PHER1l2pUpGK;3H<)q(EUUw3~5A&B~2XSAx@d9lO&$HWxhTM%t zn;fSsoWmN2Hm|sokdOAx+}JF$O4B%dAdkFv7W_Y?5U;MG?{C8Z!EVaUz)_q-ZGm~! zr5SRNFCXgNf$GvX+(16oz&$2E^OPMFz3Oe^-`))~x^@>jt2I&b$1g6UMbC32xf_Z# zQWIeP1kAlR6Zcz!)loNCyWRtR$oP8vDM#{VZ{LD`Kz@fh)uwOxPH;Tg=^YdkU-Mlm zKJdNmgJ+K`!Y!Eqa8*P8D;9)6L>1}>|7&M(>GxeS4NsLS3U?K7X%N0Cbs`FIu>6J3 zR|Z;+QWA)4Xe-jvw~4*HoKm%Y=is0uubkDRrS60Z#h__4adTYo1n9@?A0|<6xQE-Y%F$8bsa$^cdh;B11@~n(MbM9r=HNnp zX?J%<^E=a}2oS8DoA(yxa^m0rnkgoqgQ;L3@0%%adv)McRHnA-e%iS4jydNZ)2*MZ z%Hx1wT&0&J?N*8W#tlPeF*;XZ=tD59zX zqO*7}ZlE*2T1GSSsIo54$WRmKpwiD?&GJ1`z`+EFrzu?F+oQ1QI2|{23Z=K0K`5{k8PF;j!FZDI#C!4| zb8$xZPCVl9c>UDT-b)_og*gV9WvS$Ujeb!TNp)^~mmI}hr5aawj+wC&&y(1} z1>P+H?}%^KXxC(y5Z_AMKTyJ4mn0v1d*;@bN66;Jk#p(?*PD&I`^3rAHHsB(4*BLy z$}Rbpdqk;LX~>~-XNNMMdwKRfma09vyb`Jbw~Q7m*fVM}TUk?_Msa1Rh0`^TN$4qY z(K`P94OgC(*rHO3 ztf0@RC*U#s`HCNy#TkTP)E@Mee)tTLi~Hr4Z7q{+nL_tgr`=I0!8bSs2I5EVA=DyP zA%stat9@7iMVIZylxpY&@d?hkm%ThI@R_s-@jkbxM`l6uw16Y(@E%RdVmh@*iX09Q z$qg?TC?RZz`U?X{QP12pqf&AHvvl`E%?XlMvZ$TSl#jk=sAp5G-IlC9|NeohXIJHI z=+lmu%M^HmKJ14Vp+`w7WK`Gxp&L7udXOri(ESYZ4{hPtU|^I#6|@;e zp~z!xk(oubYzX)zvLPaPRF1iLL&QO0kWwz!&D>lTk9u%#!Sy zF|2n_m7C9Wgp^T}RqS*m%`(6kYsU4-GEtxA6I0BxQJ-qS#65l1ZH6pTt|&% zYke}30RtDrl9Is|h2bBs)Xf%ml6KPewGafA!9AFxJ?k)pTSgU?Ub6-n!ndlmyPWTs>{nLM5vLthmdgR#%7R<}znKvBk7^l?W&07j8I#2HcZu5M(N)@x&_*+@+fmsV-qIgfuH4_t`8Q6D#>_k|ej+{57jD69)>@NsYHtX9 zl`J@<+j;~CgagA~h2zc@kI4bAc?u=xg6z!yfs~Njv9FD3&ee3dF%g1o-q|hVrQ^A7 z{onLfY{$A<0=7;6u@t~%k7)Z&Z$i>!;o0-?&(cUzc@B*sotR3IZod>GlrX4vx(jGS zoPlUrHcc|-;lwOTZ?Ol;0H!(cv&B%052mpUUPwKyp(zt8Bc0_Fk!sx>b!(-)Q>m<5 zIvj^eNmGUElQy+_tD9+}pbj0nt$2Y4E{y7+fYo2|=648)({F&DdPM8h&^ua8HcNG6 zu|$uxphUo3lK%Rp+P9J$PeI+uyTj61i#!iQansV4n70q$tR<(jq9rL_O1i8?`7X+;O^ zhYnDTG|LQ}NOu5#UZA%=(gY6BSZ;wK7Vd0@drcvxam|Ii4YS965%DYfUE6Zh@Y?Nn z#mrDMolCnWVD<+zw1YEmk<^xx^jM)?7eGt97WHp|g2(?Nd`^{iy#dVM3!C-G?p%KC?f> zx_=I(?<4@*G5=sfoQ3qc;a?*2Y%tI8YMJll8*+C{;CHl}^g7+L_NdKV)EgVtrB|vELl^4n5sw3P>`Xf@qSwCp>QzYqnGOVCI zW<^YDwOyQ3LLFs>LeZI+#XI}%z@HE^GHIj{qQ>i*`v^`C-(`6jvY+YKd5KJRR6?Xb zM81HTXXq=+u$~BSzwjPKR`!Lg{Uqc4o8LGjNAq+~FB-z~9=Zdtq(7ka5Uam_G^^g; zn8?@zuRmG??VVTlVl)~?5`X$8l0Be)iY;cY9NZgTZbcc%I+DDU=6(h$fpr2Du^Sd7 zhqkh@l<%Sqoc=!3kPjvJxs;>XeyMd#bQ1xrON}}zD0-+4JXPg>Y@C&X2{OhN()isX z=;DD(IS4DH#wz@}jbv1Zgxv1Wmr61O4~pNkDA|t`^nIO|Xm~}+*OdBNW#YFhxbi?M zLU=gKi+In_i%ZahaYnSc_|64R)@4$+zUDTW?bC6Yj^b%6&X@uWzP@NY#E}RtOp?odZsDh!qo)RcB}WW+6f2|RtB?a4{T-4gaYn`kho8?cb=_z#B zOYOe$wN8&IWP9Llgl}83EqOsyM9vJ4oZ=5u^eGL}I|Ar-5 zI(R}=m#RNg2PlO(Y!P9cIGh0pYV;HNwg?%XW^@3U0!|xDG4aR0f;yO2JYf-C-MjjkK*8xPwFnrRNxLO!rC#e0`+mD(?Th%AKT+N1GnZR3?Nso?W+Oztq|6KnpIo( zR^v2rbg-f)XQkAGK?wc2dOkAp*16wZC=eNikJ%mm2z?(ELVG(T_*^O4Y)FsBz5|qg zBSSx`0K6bu=O_QtJH7TZbT4+fKMJ0!Gltb3I+$~qz#1!{;*?-{-)&s4k4I?VNsMv? zg=Vm*vKU#og>Z0$dJh3QU(h)D5E;dr7UQs>gJAL@PbgDU6`0^%Mj_!vTF1kM=a6_L z;6iV|&O<|QPZ9AZ_DYeML&=5B23I5H95qZO(66l{&}o^xDsoFi2VQ;Q0Tq7Fb(%xI zjiv9Lws#Mqttx{Q)~wdlzV;C@nTW8NUv2+$0*O)SarhPpfr09@w?}Be^v`eZ=Mdr?NZE7bg zIa^Wrl{hY{(qm>@C#yL;lR>2H{g5!EeI?(g0p7>8Lc%{Wn2M2->_sWF+5Dt^f-FH) zR*T_CjhA|ua}t1JeiN6utz^#Ts6L+xXL_@TRsl@flabBaI;$y4>>nORW*P<`#F60f z2s^5qa>Y`)(WsJPQ_kiVZT&oszToUVZt=x*#dbJht1aLA>{#1qs|E8PmBMK{u+$HY zaGY1YHq4jZ#H_#I+kK8&y9DAY0XxHlaQOWL*nDFF5_y0q29TdoLgC#Bn~5NsHefjO zx>%?rIpR9K?1H^BtHKaT*1Viy<#XsKJh+|GnuS}hCnz|3#Q|(TW!{Rt!gIza*gU_2 zoY`0AbIpM63m^Qu85LS=2$fa$$Qx#C42sw4?ip*HyxrE1XUl(Kpc^R~2GytM#_wPF z1l|z@{1*jx=vn9#ZcBXuvuy%>xer}=jsbx^r{0nWAmBf>JwgW{;UAS>4`3^C96sm2 zQ?{%XU-)%Q48jAZQyHC;ob`JJ+Vwcpf83vbt{_5jz@r)>vEPmI=xwE1$@qFH!sJl;Jwaiut8tifpXW z0iYS@sYa_TD)N@m(`kBzifmIWVZ&<;ndGOFiDOp3#m3G9`VHY(Hn{@`sjdlogo9Pv zrW9yvd*!Jdk1^p|p;h8~Q|y|eY?G4h!X_SY==a(b-Agnr-dIJ5mLaCbZ1eZdwsKV2`o70Xqg4VjF z8AmXLn`;qRyDJ@%dSIHrCm2@nM|gVvynTZSeFM{u)Q-Ua{J+;$T{=B+2o?ya0rP() zkBS%1KifYjBWlQxMzfZ@s~)WU)#i!)*Ra`5V}J6avo zzF>r1;c)W`BBEbT({B&i{DhuA9=@OoBZ0ljweE8s4)!Jv;*JYju76UrUH_0sC8wlI z8PQ8+{J-_zzNPpnkPY0u1x3@nm9)9IA`=jzN1`kb$8-LqRoyaBW%)VT%B9t4ura@} zpR%toBqBCMSgFgDGGo+L-`=%$o3ZGMKSBT|l`1&`=2FB0RYgMfC`_E0@##&xkQ4<# z-jK2C`pianh(u$gVeqByoL^yr|9Z&OhHfAdTf4FTUZ8=U!i(Xfy#<_3gJ zk7{8tF*?6rIHe!8np(N&4^eR=YG{2~-{R|aB2!e==yEzRs0tyO{xZhIAAzKTmr5J0 z)C|}Y_9Inkqr9JibsR!fPtMw-;rK0c&o#3}1pQmU^XvT`d;!OIQspDf8v??@&_MAO z?7y1RWv7|R>Yt19VgJA;mjNw2Q5W{VS6hP1&|U|V;+ zv5T@R+$t=#9$B`n3wZvS?rJa{39*}?=g0a|S1_T>Hm$Ihl-#c`L|SVwE1*Pcs`@F!p*+Qytfw z3P+-~KEs^~p7W5S9)zPjxSwFR-}V9bh}@|75SLn`A**7f?S?AK!Dqei&||qTOyjM= zpv?+?v&~L*wTm==JeYF-B>@S5hD$Ft((0KWJrAT~iY(ME6s1jE>Ku;L%Fn~-e1Ax( zHf@CV1gGtk<*soxZT_@a+1}fDY^sjakK?zFi8&V)tW12klpi0u3IxG&=E-Gkj>?NX zG2Yyx`}0KfCBmiM5Ottbo8zL@TD7I6msqN!+POBm;l)^M+9}q%n#>AV7;)IE$%e5D zb@)jZ+peoce~fQIn0*0d&9ZmQHH&@HNXfyOHuC-u6wGOP{$r>mG$B-^(3N-fgV2R$ z1v}?dfuNj*{%cH}x*s)<08kCB9CrSCLDZ(4*tu-K*`_#q`WM3mw}Y25+cHhpCrw&% z1%53m_!HmAXVDtzfL}9Zkd8&MT8TtJM-nMWN$eB{by_=GR|m zBaMA|%urprjMzL|+_-yuTBMMfN5-k$5N)HLn?3~+EYMP{prW8KgLWBCQUqmHc23CY z32)`1z$3zV4rYzcTm>>+ZEwxbvw>~6E|IAbITe^Pt*MN-y2t?_?kLq*JWPkSg;Qkr z?wGD~!xXhJLnrTd33kp0qboD@|1N1c+~ioF#^_0?+5ZwaPFRbecBv*9s&l))>R*(u zc3l+q4Ycdh^Aex(FSmeAT}3_*QM3M&!RRVImD!TP_RwN>s7lKZ%qC7Q+{(3-O%6@) z7-f}t9u_}S_6`N0wKXSSlwI&a$p&7B`iV*#%7RGLn{y+Sf}e3tg=z11;oU+ka689n z+7k~-76J{_TIWM8VH$P|rI7Rn^Q1k1*Ci_Fm-#pqV_PH;@)Z5$xpqP3`kn?XXg=P%PUV<2n<)350bBGrjD1kgwGM zYMlu|if=O<=yev3_ijqN1;PTgSfoM2t3!q5GQ4JM)KcOPca&oGK%YQZ-zGBc8_Q>x zWe&40|0F#Cw1iV^4RK3s*2A>g?dwfwECf<_g3`pvDXseNpVkdw6#~>k(NJ%+hRQb} zp2imZUj%o-X)n#V*QOFVdEtoB3%FqwN`!@Lv$}ms0RG6X$ZNCc>+*=i)-`@LmXT(| z>Est7IWB80uQb1`%5e@~R41l;Ar2_bDt4Kd1^GHaTyB+KqAj!q#Om9nz=O4fRHD}h3-`?lAN zmTnmL&Io}~`dRu0x?EIL{ncQYOP(Qa`NG##Gu4$N+lPvG=|`+%-yrL$E7C`0L$9br zTkbCa6Aof_DqN=D^4LO8U=o7E6Rfsbi^+w~%D`hKO@1)h5Ydm|a94cFRHjwTBnIJm z7(|)La`UnF1LdRo!~J0sl&cJPP31sGj=C*v=&E=D7W-xW^s-NGIzD3r=Mvt6&FATP z$oiD9F*cEDS<*%xdITBUIto?4Yv7DigXAV)iY)t@t08^7E5u48?3$>QZZQbfUa^@- z#rXgeB5|aBV=2BMT^PGAk~DH5kF;}0u6s3Red0HT8H!b9u%>!U1`93<=fZ+#)A}lz z$+hLwOOY){k(rh&20V6(VWn}4ZXL3&UBu;~%^BM`Gp!SbISo0EDosyKmiq(jJEs z7dK09*B9E?POdmtwbqYVM1JmME`(!OxRpV^q#a8zJ9$cG!6lRlXSGMPXR6Kz8_PJy zHF(_c9V8nnpPeUiQ*nI95EZOCyR`%`eb}l=i|*#KWrLb!b|p>d71NkgaAI2%8%WgH zQI-9sBu6jRD%}3?2=dUwA*}}&Dby3GFko%os=4TH_Vl}mhzSt8kx9QGJu2+^6?8>6 z8GUs&{toRMyrwTI+97a}t>7$_&+k7RcFIeUWcW@cesBHAYLW&1;TZGwB^nLTm(5s+ zaxnYk%21caiN^{sh3a?|AJacu1*AG2~dzLmCZfu67JN_mUsa@D9=u9eh_EJ?)*LLz-P^D+? ztl8tUpKo1l-U(4Z=2plD0Br(>72OPP0s9rtv5&alZxlB|bI_6$P7$LaXOS*3Nbg_k zR2{8kao^zd0ep=?3`b<5*D9cowOMmWf_gFEKwq5%0ePSDn1+4g*+Mr?Kc+DuXFZ%C zKatzQPnaTXdn{;q(5QcGH^m5}Rv7b~ay5c1n|eJ+F5J9q@?Xa;+*SYqeSTQ{k%XrB z4OZK3+e;Jc>nAK`{q(3FdSI(xy#=+6{(STV=l=D$tmPa8=!IDC{;g$1DIi<06QH6^ zqNz<&b7pK<=uZWNBq`y;oZ#+#%UvbA5oBpPRftV~67)oDiv@P65uPMZIL|jbzs9Ku znu&fguyBu2D=T7oUt9p9y8-8oQ=oswuoF2VCCggGbbcdO4v{vtlA;BuA0VSL)`WYW zw1+NooBvE=ldwjn#A%Q(6O-=_EmdlYb(99p`=ef=7N?VSSfvLC5xNW(8-Z@X+Rs1$ zvFVN%*mE144dp0Gz(!IS1Rh};^fx+k;v(KziFF8+5p@uZ&tCxqU5HP&p4&-(+ZTd+ zpKy|j*!%-U85Op{mIQn{HhS3bkH=~X6`+0@){EM}368fghh#wO$6^O~P;^hlce%YE5~5(WReZ~sA$kzh*l06|hj00S^E9MHOQEbfNY9_C z4Dl^H7PdJq<73TQUHn!Q4m04v=J3ldZyy>-2cLxx`$Jf-|GOVzU?06hg9dH(I7k#a z9haK@BkYHkxL?u&PYj6^z31%d6C5y+fwO+$eoCxGX{`=8^L1`H_|zU$bbF|7{Aqja zK`RO~Ts*b<6^2o&+weZ@ps3re<920KXA*>mY{?i1#=UhAZJlB@x!J)?Fq{WZcuPqT zL)eObbm7v2h0bXwtOZ6?+s)Q9_RK^uo6OQC>nzla%U@{=426Mg2M zpnNsxm?r^<0=vIueO%~%st5+kEHz^RpkomNnC%G|{C3@gf&lfPtMbn~YvgwBmE zT)l26ww?~1cA-Pqblo9C$h_RzAfYBa`K)2Fcj6F`TlGoc71NLhN`V@=dypYa-euHqZ)QXAPIHCm5}|VATvP-JY> zn;Fj7oU-TSH<}WZy-h^byXj-GKtIM^!^E|W?GwKc++Enr!Xf=atZe_*V>sDQf%w{u z{UGr+Q#Q?lyx|Y%D!(X#SIc{b&)o@r>9j}UO@mj(rgI9O6lvX?A?9DYechINnOrUa z*j?KDV}2qZ!Ttp<&B@$i4im2*G}VxjsTYWaH&c0?x{^4up1jK_4$i$R?Aw7bTo2wI z7o8Us_^+>H&+;Kpjl6KWz%eLDyLe-6zg8LU%LCN=E_rIy4%z%bp1iHX5)F+x=zRdggW`uxK^`2F3u~LD8=}x0?zoK zuZS@Kv>ib|uy#Xlf&L&1YZVaAm_4lF8?PBvYooe*><}N87BglYWIYwW} z4#)|LykTjayS_}$OPOFkW&JsB7_1YX|!-nEo*UlQ%qe z2LrNpMalb>A&*3_gr7$mK=$WyMt)AI z{P6|KzRMlHiBDF#a`ye&)FxHSvhKuL zL!ufpwMaF>woWxdeQL#dU8DLdK3OeI<>cILw}gEwNk#LDF2t0Xg3UQwTS3GA6%@8ztctcdP7Q9L zH|~-8$z8DvDX0gr>w##@`{lf3?ZVCGz}LgL?3m)`K-Ns2;gv!3JER^^2=~J#$}jRt z(2M;I%8z^f!u=|km3-!#%Ib$2&H4a6^EmJMTg*QQzkQ$&-f7Ymy3A`2jqk+cW?&wP zWcw_v#AF#aELn7x6HhabMhJ10qCZ9>Jc%5>z0_@Yk(A@9N<$Bwx)Qp2dth5E9!XG4 zxiF06FVP+fRL`MyrW6Grs!GH^A3V-4QIS+j*&mBx@JAW9H`#(dGDd99vx$Zdpk+fH zNquy~N*|G<+(f9?F?9!$KV9!G2n{SobTnW_gK_c5h9%!L z1YLJr@0uJjF1IRTR;ke-hrJ%iM{Zz?qO(Jp(zWr>xkMZfs(;FeKmk*A55!tc0$xg7wB*ni2^$j<+Qe1!d|_xL6Otd?59 zxy4WrQ3|K2fez9IM@2l4mPuj=8vK)E#jqE+elyH9M3}@lX*#3UVFMA{bV6Iid6p`j zm_?;|i+9)GoU}$dvubv=GRN-3Y`6U5RZG|Uh7|O6>V_S~%_}(}=bHn;4MlFa_GBq1YtB3?E)+;QQy!FZ1R z>cu3+=vOUMl=<8P_YgftI7n}SoKtga$Xs)ue#l|wWZv=feS^*mVhuScEHpo2x5~!( z=(jDysi?24DGNDyO_?H|aAqB`hMWgAgu#Q>vbk4a&gfr7FeX<4u)DS6MxZURvxa_T zEZtKiM-1)jM!@}Bm1}3SK@uceQ@v2@AUlCZRHu`;D2x=86#006eznxFj2L>pLC6qd zG8G9b%+qAk$8Z5&Vh8cp5avs@*H<6RYl&GFi9&)Q>gGb=Zpa?)-Lzs)Q*mB*+y^A{N5v4_m#O zGsciyne(!fYz9DM}yhd{D7%X*MeZ^3fU2EDn_9ufQEZ90ss(alQ@PG#KMRb@;gpoh~cLghg zcdfcQ2Wo{rq@zeDfzn>_z&VpQ+x)xAm61Z?kLme2S+-EfoR-M1FQk`T=`=#!V&PW~ zw{s#3%29<_GzQp(%y`*SZzh2URI#(lxgC~w3!t(7i5bk?kD&0EIC+S~Q8%L$F2=Kd zahc!5Z@{UkCh`ud5KL7qv;c#sG*O)khGO_cOJ-u*~hw(lY`@r4)E} zZg}^&JYbm?T(RPT&weN;fTs`n`D9_wQT&bW&?c1Hw>G#gfm8g%SI_@Qh2VG^n%e&s zVQBq7sj!X#Au(42GVyl|0RWT{ahUwMwmHHVgtSzxL$`{zN)-%=2P#77X5rF>-IlGB zWWx*bgP=Q@yzkF{3aawlAC$D%n^b$U!-tD6P$027@?F!e?%13|)TKZhnh~Wb6a5Mv z>ZU%W6SmR&v@~v}pqy7GQT(!`#eRBb`VnT9oc9KaK-frupG(YWK*+!zrMd1SJHIye zKyNAL??%#03+clq*|eHbPrpb{77i>CK^f||O)$c|r#SlT0&81|Uc>7I21iUBXnb6B z@b+8yiN|^G@sbc7&}leYfZJlXz@vn-W0{|^86_Lh#nhz_$|Z&0T^n>M^3H(n^f z$#(YhA!JQjv;MfibW7CVATD{sZpwl3C@t+b4HtE48rI_WvwmN2HofR7-T%A4@pgbV z@jv0y>VNClLt=#i@CsydLei8;N<$@rj6p#f5g9`CEfU~3dB`*+dbcJ{39vF|!|ei^ zR_eaD;!Ozet1EoLEmfxYJ`YnmD=E7Qj}=?;U$uA0X=GH$TuvMk~6Et*6ZVGg<>B2Tl+ zdkr#GRGfNzAp=;e>3dw+&1JYg#MUgQj?3Eu!ud@2R@=Rz8!q%N9^JNivy{vt7gQGp zm)bkH9JV%qrW`%`a?mm5sR@TNx}M#{lSuR4m;+%BT$L*|tzn6nTWohJ&Y7p3Jfld) z6SPW*+}4(CB`=>7e;{OsN|0khe(fH&Ef$1m$+`~s7A&D+a~G|U2?s7eHc22}mZBqe z7i<@tDzQAcIpwA5)?(L%;Ho!L)_{M6UzYi){j>vMy2+RRgfmbb?Jr>=E+vD5uksK9 z9fJ!dIz3aCH74uZuNDlXM8gnFIg5~^2*~Y}fM1L`U<*<5!yI^SS@b{eGTv?zwaCoOABE&qHJz3F50^!cMY|-nmM!0>IrPce=&H zArqom&j-z0s*4Ep_3h7ISC|x5;sg*p0ZkAePGyCIwM5P70R@YBu8#iY($O-hatq<7 z^-&H6;)4y12uHcr`J^en&y_qIBR7xTTm$<)_m1;-Yd6!kvv0TrX1f?0Ug0IvDsTuV zDEsCbQ`}>K;?ZJ=)1nJCWNX}J@#d6@VNN@dvS9QH?63coK@&_5i4+{(Ci|5}$&RT6 z=sVm-eR!Y9l$1ZNC%NW-nM=ziPq{ZM*kYceZavh#SxL1LkpyGg9PR9GwSMQ$Gd`QH ze<;Zl*80%>LNN46k@|PS9l5X$?#T8Mh`}}{tj5*c49h&}C516g3{KpL+7fKJ7k)WR zSU6`P>QEe-OL73eRyqHgmE%9|{%oi1&b#9(R^;xUYfhSd(V5E?Ll$hcETYA-#t>jU z3LOSfWtV|BwCnQ^#cOe7KSlZB-d#sdlD-xV+`7Ybe|^2<>Y0K_G{=pe`L_K!3%;+_ z8ysZiYOr!?0YOsiQS$nNeTNp<6h2QU=3SZf{7K@u;~VCZKr;5}p8rN#R^z6JKNJ1= zh(}?};%P7TtV*K=snD3qfP3R59K8;I5MW=D{Wh|M{{w$+hnw;%iDp}onbnK$LHHVE zxUdSoJ4_CiA~>8qG{_kBT&V+^*Tw2=A%{=DoS~N3c)9evE>nU=M9S8MDRlgXoVVjS z*3$0R(RaPT!(BIH44V=(C^NnrSsB7k0-tstVqGo#lqXNIu6Eo_P~PzvsLo*mwt>S~ zY6@Q?36+s4lWC25oYN$-LYHa68W+Lmj$jFQVxSim)5IS>T@MM8J zdFPG{C3*Rl#J*STzvlsbD^Y|Y$`H_>DlO-Z96Z(Q+ z;Sz3eOuNs-yt3Zoiyh*bc%5AcHtB_Z2rub_e@|>&tC>RoBQwC%-0G|(5!UZ24p?ds zqi?QbY|K4tbKARN`xC{b_#Hy=&B_CIp$}b#1KfQA72^>Fp-b|hU{rp3U!=(GJi;TC zq0(5fYkN#f=T}BzPeOFy^#KkWDJje#dZwTA4BfElr*x+$&KUpIu~=U0F|{Rbh(Wj$ zv_(I4iaFTF3K41ft@6hTtH})6TSYFYsjbS8A!4r7bT!n9m#%KcG=%k|wDiI6=5$-D z1|Qq%RjmbTc}d=*(?rU+Z%_pFn&r_+LQX82Zm$+DD(NU~QIZigFBv&n($ z)aUDrKDR{t_%zYhOSZ*ck;4AKtoB?0=`b+YMxL1rlBfIW{$g$G1L*TXRQ`Qm2Il@R zs{0sSjk$%`MOJ6oAVKQ0szP#h$6XdpzSXadeBqEY}Lj%2Ui$At^{G>1@WFDE2#RWDcp)Z zDZd8qr!W$6V^K3wxEO1*8Qs7p=eVUi5+S&7@*PKjo6tzvkF{Dd134~TckK?^vZmlC zj^mV1b-}+s;@xjHbf<%6Hs#RVUFIAFks5MGh zP!L|>T{8|=7EQr|xh8AXP&Y8;EM4vaj3)nF(rV?K)DOHr$#+zR%}G|}`v|8h*^@7A zv7ymMW%S{7n}8YtQu!MG=$YY>sJCPmK9b)EAoFf4(ztx>cbO;$j=^UYyO#(qMeEHxO?(6*h zZLX>Zs~<&;I}M=rH$^=fza z>q*D-E;498Ii`*68}U=EbNVubprq18)D=RFITx26Sbj*3_O`TC@RK%adcTMf&Qn&r zK>R*Eed%nujs-OBSPsG{p$-!u_K>p5m;Y-hejM!+Dw-MGyJEf=^f^e zF5{yoI3*C*A57}VM4uRY)N;Tf^pb?f5i$Yk{)N<~eO3u8dJ8%+1L%$iBV5Yrdo%8+ zxap%sOc^wf8l4>$ue)cfn~j!qwztCss@A21$4z!aX^*5Ro1A#+}&i4BEeRO_DJj1!`!ppS@xKbXVfmn}oQ{^$G zlln1PZ4g=}{;Hq};!5l}=v{H(r55i6(|d`CaU-wLfYOL7fqA{*7n$vd=`WyDha6dw zE;VpMIEh`FDe{w66G}twH7ahE>l0q_?8m$fBfztDI$SMTk}T{^z4@H0#>OaV@ciB6 zYV7^4%Cafdyq>V;8znts`Jc=DjS3T1Gvcpw@N@w$_bpYdyg8ox^KvYETXpl1dw|%Va+yL{x!q_QKrx?_xZ|=_Vc#aTo{w=T1e=8=ibs6|8eHZ+yAuFd`Le z8TxOLsh(srypYrCO&3EYo!3%+lt;^7AFN=(kL&W=&mVeARJFIK*U@q;ZoEI?_4pjV z)481?r#e4adM?&n?1*(hizG`mJ9ojlwy68x!t&^N;zqKg#a#CkeoNhdKWWpGT~D<{P3_vquYB44KElrEUzn zseP$Oj-T$%(YqCuAy52n-x??+le|j4VuWoL?~0!1@~$#;E4#B6JdE>KeZEz*X;!}g zt!oHWRYAPeK780TcX*yzZOBaC_24b5W`xRt3&rKj;+U4@Esb-<=kqst2hUr5bX*-4 zU~DGmD@c`JG9J9!Hk2#z{f*h(7H3YIkjjTv;go3bZr?>x&4#`8=E5pI(k`jg4Pp4LmD5;5iJY3OIsw|t# zGO}9AodVbfw3i89l}lsaWhcT)hd&7Eg<0a`)5G3PhM+F1lh1hQ_#@jTf*!oTv{A*L z&m32Mwg_9IJMgRk?F`E}i~c8bqp<_Sg=LeqCu>WWc(#VE9X}kIowd!(mt5_pXtn8D zKUvh(kaUiZWy;~U+h><&$l}E3VFsOX=LGfX3n~u_=nEh3nGb6r}|m6!)i6^6uh2PL5ZyOZLn;8HYZ7Xgu`(UuD~Om>`n~y8~?_a^(d*P$q2t z0Cd%^9%>HrYS2`keI(mabqHF&SjNE7r|U82JwL|-|8BjUk(y+qmL(_-#H+VLJD zJ$;8GaHGo!k-lyzZ&9PoQqPqlioXIlmy^sssajEXTfzD3@Vx*pRFmJdFN9vd3L38-q3}`yOHlvZ? zY|A!xj4JPx9acQoreW(0?||OF;!K-*EY?D0(G3+0@R@oY=hRh1(!txL#=O&bd7r?3 z{gZ_+ikCWcJT5*ox|YfCbjbVoq_=^;p{RdkJ*Kx+!ek=96GW=oSr)T+S+6345d_lW z06wHzvN)4kt)75DpfW(_sRnHG+)*bH%COOcvdM!e9#g+R5KiEH8Vr!(6au2sAh264 zdgw^XAK?JSh*X>gOoC8BNSc^{w%ScKD+=_Q(t|uf0|f);(u`qsm&pny6aj#e5UxVA zU+*AAKrOft#b$- z0i(wDQGiBD3#rjS2{Ke@7Ow>RBi-t+whod9)Ss!te+SGk|9vu=6hT0Zg4|Ap;M9N= z%6ZMDY|=Dk5s*8SFaUop2H%T_`1=s8RY3qmMU|@cJClG?cXb-AKGY7y4?Izmr#8cH zFMA4khK8Kd08p8h@EtF89HmN!DS#{ua9SG#6lk8J7P#jM{da*fx;qpPAeW^J-?PRA zflktBkqv%PEWlNLVXEezK5D`=wEaK7Xl6hlTaaPbbxSRqmpC z2tlLMX7!7fgYT^e1c5|oD5B^8OCw0Y|6H_ojD~6r{6#SXH~j^uCGSnif4=dxJv|NQOr9MBFZ! t8b!T+8K~W6KrV-uzBy@k&+aI4S7+~z1OiFW=mWbWLH{s(Q46{`RM delta 35599 zcmXt;V|-nG^Yzo1jhhoUwr$(CZ5t;%vDLV-Z8x@UyRrTBzW$%*{eHD)X8qQD*YqBM z-!FpK+I|N{kHhydqKG{OzJ$I1f!s95Y7Cz-Jv8B4s)L+kl@0pru5$C4=2}*XWvE7S zpkKIDbBjU^=$xex2;-3*TsKjl; zZQqNKd^<774daff>xtuB*-V&lkbno*L7n_B7Y3`)?*QITl4}o+U`kC+7NtV^Ir+v@x+1=}mn_DjBZ(YF4wDEpcdfXP4v) z*mwfrG2tnjMqwaTizY*fW+>?hy9n%J?a;|*x)r!b zel8a$wKVp9^myi3SPfl6)1S&pzngrTOiwoec7K2|Mv;M@e0-*992&Vf+(T@vqcZA> zFxmQDGUkr*?l%(m(}VW9YoU-K`Pe-bfy_94D{$KKzv=9qcu>TutWxl{Xh*{fx@#5L z&5z;EHP&8q=+=t`XLgF1+xnUcX+jwEqVhZXkR_w`QqtSfrAIM3*4DobAMUO=9d zcD;;;FRAt~8;zm%E6N6scwrspDZkV+mFnQp5c}7C)6UsF==_?x>7o^d1cLVlf#Cs0 zjW`h6d5sUlyp{{1k}-;H4o!HwAe)*@(v&iH%~U%ANJyznVn$!=JH}{NB5R|2)F4v2 zZ5uWY(-p&$9tu6|Es9>|Qc(Lu08sry~p zenSb@&7|TWDbT>$Q3DM16iM~~kV{uFA=2Kjwb1yQ(kXK6g0woM@7PU;as~ixdJvj3 z&6qRpf!XeiXQ1qav^?J$iEEdNeg*Hmpr;*KvZn?Bo`*()7tfCrNDj6+c~(wtvSAtL z1QP7pXa8DL;=r6h!{v|z*U}%3q zGAkLJ4&{Re)d#Wb(@X74eJGhjjJUBzEAj}tObO+%*bN8_?|JGoVF2610~Wd)!-rp= zDIy!DrSgRN1J~b^pxRTg{f#e2v1BoN_NIoydU^!D)u}>x#6dBeVy||C_wo--)2ja! zx)S(bGuoO~%h`j2fi)xrq8k7&L=6MuMLaKW8AxW(Q!d^P)Z0(NHp2FUegjj&fYC(s?}mzg}(-{(!?H z=ElbAtMdcc>@N_kaAiPh9MT}nXQbu*1YF5^WLu#(Y0sdrpsWsF)+(T$(M6b?0Bh>m z27=hAC1>$8ZZYm~DINWk4niDk1$D{0_xznD$;ROkFI}jsE>(zgkw^!OaAI!_++~3uw`y0 zVJXjuGlqyX2_TqiG;kcoCgiNTzz@^!S=~O2?76x>N97>yG?{wGgV-PV4%0FZwH)fD zw0D@;2$4gBn0@1K55bSY_rq$0Gd{SIxQROYe$55{~Ck4buZxw$6j64YDEFEdJ z;Cvc*g39!R*fxwu!k-fMXvVBwg~f?B4S3vGoV#u#mEUX6K(o#`9*!Il>%WWv=ioDj zjHIo029^OaYdN*V)&Z==Oa=S=1d1Y6b2KI+L&Qs&{&J-nokwsJDk@g@OW5N31O-|G zlWv8U6SLN6aOU?3a+uBN6eActMh7%|4#}T1_=+G~#4{P+%jY4-rv1z!NVxjd++Qp7 zcqWC<&5l9m2HISAtltymnr^rMOnxt$8O@-wMc)TJMQ$^_9Yq%;c?29u)mLJ6BS-Z7 zuib1aVbXPygnrlpZ4~AWG5qxf;hQM2Zv3$^v2AJ4XSjZG{Lvx)?Ig`C%X-zGRy8+1 z=l+}Nl|}ZxK|l~4ljP=ha)8i`SI+`cXbfw)^1^59IO{HJ+~;-wxP$>r+$nf>@$T58 zUSW}VIW0s_nL^c1Nv^EjL=7qF4P;`Is)9!95lYocVcF0JVj z5t?Zbky7h<>L+5t93s9JzDL2o9!F1v7({5tVnQH*h(6iv3=U^fmLYi*th#qdEPla0 zDO&oIRGcCG7o6cFhpi53!Gg`lO5p z<>s~8EEra&BJs!gpqqd1U_gVLJArOS2JC0HXVOIwJ01j{>DF9aIH)9v7v=E_nZm26 zF|3Gy?SV@z@|xR?(U2$aq+eA$r>QonwI3C6ZnKiRlp@F5X7P@oyqbh0O%m@(Qi!@* z8si%kecx83bfmGKH)fgPB=L~Jvdev)5FqeP-SRhv>`w|4ykl(dmRdAuKcyi6{e|iM z#=Ary1-8D#bUc!TL&t4M>zC@D6}C!i-wZQQ4kCBT5-g`eOKf-RP)x-z}SR)c(N$b3jzM<0`+6J*!8(E#fQiOLSuet4lBrT~ z&36eE!r%TPK%+;VAvCwy9U0deBBkGpj<-g}m?REMjOvyz(G8)QliJ;Hx_cz_m3y~> z%WSfXN-WycQmqvZ;5n`GPv4BC35ktYL-+=2GCQA?NS*eWq;E_uJpvgkr@G)Kd%*rT zKTwk22k0Td!1Q4L^IUDDWJx(CWWa3oQx9}AtS>%Rvo%*y?WOuoM4{huN#Z~1nma9Z zP!kFd$(sCvTV+`k<^xA%v(g(?p`QG<2RAh!J!V^?#++UbV0ygo31{{Rcerx)DQ@^# zq;Mr`7Z}ph-!^=5w?8)Nw!dBum%-TgzYrM+`PyqP9%p`M@DIq*Ef7c}hXRT78dD}u zL1$;F*pu2g6m648)!bR%!_+7;2#!ugO6h$O?bn;Bx?Y&) zn${y9MZEfd2C`I&bIek3u(Xf1Rb^r)#yYO&bx3Y4wHGzfmER=HB;YWD4Cltyt^8x` z9YN!CJm}*q<>uF#YcnRB>Ol624DBr53pKm2^|ZfCRZ0yU6ajCEg%$0(!U0Bil|z_+ zk61=hDdgM1X+&uK1O0u2zk^=7AwVHICGR!sRsG4ZG6V zc_NbNRBcw0zFNbhTHy8^8(fvBvVrxLJa!s<5rCbEmKUo%gf7`9*n0v0v2=}YpV=0{ zn1;T@L2bU&RGQ=xpLb;5UgFLlTjRH$;@U2%DCz+sz4hH(G1nZ?{`LwgX?cyQC0CCb z6BG|}iC193R0HvCp45r?%9a&1Z>Gy|GI8iw=@}*0I?gOxHIPaqwF;x1!8+by&_UO1 z-`m2(2FV?bqA*d7YFk5fj8VJDjGR3m={6B5xo{Ue&H8jL)L|B-Y5wq{C&9vLZFLCG z8)}NgHFHuKWX1;3yCTogx!`o6Au_eY+WatoQKZ6c0HQe~V!erS>zRnDMoFuKn^|z? z9l<6emHcQ4N>nv)r!@+Rj7l7>&6{(i#2V#{uKOwOgquDAYTyLF`W-pCx{ zn>QfL3K-A*YNtC?V9ZQEY|_LTq&ApvuJyWpBn85c=-fSHg)cc@Qxb2RWbl0CmBTFP z*ihFSH`mmz1YD(VLUD<`)8?Qn=9IwG3#45WGYNfd4amkjA-DQ1p(&L7`Y)eB#@`tpSD1Hr|R)Ph@*Da9Bw$L_zMgCIBqlq-@IQ=wAN6SP~hhox!`x3*;x_Q5y=;5 zT`a{~&)Pa0q<_k39POgGaJrK6*`6mIstxxSc=!a!kbYwiQGxlcDraD1#aFxs33dk8Nr*$b zG`|%*#Eiimqn1>1=%lS1V_f-FlP{v%1Q@SSAb^=8e5R`TC*8dxSr{dj%(){#w=%z` zi6HN-u4ac@+@kLxUwK)1hZJ0mP@V@qQF&IWOY^jw=`E1-?lhg2?J{%7P48EJ90#7H zYSfAkB$65j1q6PfFAhi18iY!#7v8C=&x1#)4I-<$0x`=>Vx*`F4Gu&SXENg|2vJ)5+B|Ehy=OQTMK8Rbja!X6nl3t0F zNg?2M5(4E1I2wc888$Z-+5%=NX9rA!P=ga3JT~>p8e3%6>5?3YDS^F)&$T^Y`8V=5 zPA&=~&CTWM_*I4JIqOaM1Zz30x;1noR|pc@@^mG|ZQ8BPmP6{4>j`3)L7*WxfRv*{=?vM=hUOqo zk#S0qJJH7wZHTnL5UYZ5!=7N257txCDCYUe)++1?`|^web;N-s`dr~|oqA4jUXiiD z7=C{K*B@Gur9%gupx^$j=?CfanGT-08hG?oW9ooKce=rK(yS7P)* zJL*(R2dygB>lnhC#EUKvDK~i^q;S9FBiQ`dNW%9cFNYeWMh$Tu9%LP%+% z=)eGhv1fOP!_-PSd7qpouiPi+t;eTa!XB__qrly}(NXQ!f{f$WZb$gD=<=&lDK&;Q znBqach7(Kox}UIVeP|n)rW=RV#lS0gziqnJYVL-9It|iA2$6=DK=W6em(furKii;I zX1~K8m3mt64ZZ4^Idx9ZDJ+rP@Xvci$uwis90CGDc^fFFQvY%o6WAIo8D*>*IT=P- z%%TKlQU*=pA{}$*ofSQ(9xz(ojw;|Umgh6J}bA7P<*BCW+25KsbNB=|G8 z?|1bE8s$8~vZ*=tS*PASKAp-}0XIYvE$nj!*<$tCJn4QXI^I zM`r%-OiK1AOM(qpf_#=}0^q&!d8B;viEczsyF#b+;PP~E#-c`*Ka?M$+}=nMFG)-y z9o}?NA9bEgj#Uw}^6ft6{DV1(;tgwvKO$q}rikKoG|?Y~P@Qb8$t$?cf+;^y*PQXh(hYT7Z}DNr%8Uo!N!(Si6r z4K^jfq?9A1#nLIQ+%{^k#!L%ZY6ptE4=_v`tlqSmjvuMb#i${aVRStuyCvX+IuXKz z#GSW8?01GZ*-fQWeA$BXNpq3P$Xa=X93q9i~s6P`*aRUiPY zaf`iCL8Bi_+UDfH@Q8CvGc~=S&+CYow*T2!21@f4s>xgt-P)0cx=U9_#dkYL3$|tb zG5BB07eQi^to-YEX{i4;2M9_DV6Qwb6AFG({0vxN>JNFm_A??OS{-FfF-4+pX!**J zrDdFscit4Z!OI=>T}ouC{Dr_?xUw*RFv3tk*iUbf=bd9Oha)fZ%ge7%h=A{vjL$B9 z9|b;`1G>8T@xR7u%D%NpViY&*K;A$-T$w z9Z$x%Uu?A^EC(6V9(<<4zG^1(Z!}L_<*~Tra=BW4+dp2u0$Va-^yTGQcj%ng+2F;@DRMY7*Qq%xzJiWD zNZ9uQo$CZSk`?ac{T~00jMP9f0i3Tr2fdnSjw`A@{9)H60LWL)uC0`2o=;P1uvI@_ zR3}4*;M*^pQu40fgeb;Zps%4*7q-AURPyQB08&p*uUHHbS0Q>TWN*e2f_kr0^cpZ* z3QN=H%Iw~%$N6l+k{?^)L$$Y%_A-$3H92BP`zPS8ZZZyX^w#aNVOgX}fP?WnW9F29 z-@EaYn*qw7fk&h5oMpxWBA#e?#PktD zX26m3p%kVpwm5XlC-p~p-nywIzzH+dA-lAnQ6R7JHUR`hYwiT&fgSm^)$^Bo4vjkI z?JEzN+cSO;jUW+@7uJ#sF_RJ&x}@}` zpErki_vC1F#LcNsW|9{#}G7f=roDaI2ICVrS7#cZ#z0KY!GAOnz|`*toL9~<5F zC3JQ3Vn6H*TtA8#WY^LnkLON)vN0)dejENKfxi+nxNGD4@s zVrvEp6bVDinItjR@u~yh$@(FZigkzWl(~1=MLJ#)v$Kv*gd&745|O=1Tjl%qPte3J zh0=w*G_2FFm?(iuxW{*l2!zx-LZL!spA}B}f!G$y%KrF7QmgN+SKPgZZCjr;%cGn7 z9ynNt<>Ec#9lzo^cFldxJaVA6eXYZKvt}j4dy?03?+Z`+uE=b}d!)D)nB4XPhK3A# zp<X-ppUpEj+wo3VX=27o?w1;c=&Qo&fb~4(ij=ZYT!>AnpFz1 zBb|}Z{;@PHJa9zikE>7Br%{#QzewOt7vn}y^acOl$iJrlg0D(S_@_|;s5Ag{QYIYS zfAl>(qHVK_7U6AnV>5r~|LA+6;T|&KpD^YrIx$>QtLFw55A&&X7MG{b*N=UQ0IvyV zUw%$crO#50wk8U29fO4`yRK55JOdX#f(|3Y=R7(}`cMi_Qp&b|lKwT+C4JQ=5eegqxAkR7Q_XQ@wA{cC`-yR6f4_#HByBAhE90YZl7x51q za;Aj5SdC2JE^w0|yDr6rBjc=bh}9J*LOkKU&~1Rxd83`6Bd3j)>`T$9z*DN9)&6l0 z+MWq9TPa>#{)41h4)S7exxAwp#&LhW!646)Y_5zi5{z>CeAp zw}uuoskR&$7^9}AgD!#LKMct+&?u>DOMAw?hz3psg@O8R8Ldeb|5M0LR3>bbNNeTq z&?b^}mHzX6`}BU1{^QVkv-aW~x)`-&td>JP|l-%95&f5EDLEX$4k0G`WWj5JMAa-*~`AYlG4ied3J)tPG%i_lR znWIhZ!5HKT=XuQR8*3`H-Nj@gzlr+?HygeZxbyp(i`=Soa_kLe1-E%sO|pKpKBh`E zEv%6JIW5zxtFwzUg;QgqPe#Zg6#5l533Lram48M+MLG?yI+M66U7XuSgL-35VsxI< zLwA=F2+RC8cOT&&Xs<|~nx250RH;qd74-LY=FH8UG8+OF53?jCiJ)_VR!Whpy+G;i zqEZ_QaW2#7v22n&@{Vb~(r6pwpm7V?JeFD=L^=1x7JY46PiBZd`&*ZkjzcE>6oOW( zwWn&GyHvmFvE?VmzkC*&Adf(zc*`DCA@oOJSl;jSJg-b-D40IZ@FQ4a&k|H5OC#9q zf`#+%8SKoH85os80Ffwq-F{SWbGqlC;jWBxLJyjtr&*jKRJ@p<(SCD>PN1cMiztKb zYW|U5>Q%Rn)_%zu-AT5{yAYuMj+w$85$K{Vdez^m#;zoV+#JCd9m;sUQoa~NaE)R> z6yXBI;_Q>Mq;W@brlzEpO`qRWj5pm14Rmq1sXW9#u)o`VFW*89PK>~4CvCGTx1tWY z{9={=V1?>h2&^8)pYF2qJf!Ph5+*h%nZ+8S$|7Q>-Y8h#WxTf^G9TZd3h!VuvNDE| z9y-emPiz3hCnH||d7+lEyK)i|B2g#`n_tm!-RC zBoyc!$5#%CjANhN_909WnWV%KRTU2#QAV->1Cn*iA!Ze@m?8JBxE?rgFN5rUd1g=s ziN67=5|^tB^>h)Fd5AS@qoatxMn+D_ul)68%n4<{z0OF)n?9sjqjro?Rv343>|I&uU2%?xC}DxF zpT^2I0Uu0M0j5@|YtjZFj}NZ^@xsx2cPsaaT!>jyC+t}bPE94bkEz>hi@}A_+AGD%ji8KKH zp%Vw4zioPd_i-O1jGZbaO`viaOwP!P(|(Hc_z&UrtKdn^g*QHXWQ{2qmQ9gya^&{B zblmymGR18fjlJsN2;4Lv$D1L8fBpBS=8??2)&0{q6WIUGE}qLt{|VZ=+3 z?o`wAx1u1asPsA>&iWjVH`uy1WJaT8GEQmO=!87?g(>-zY`bBb=?hqQKqpvBtGeAE z+7ucF-R^+2?(m0gEK3yEOi>q~>o{xw9X|Q4=W?rxNXZzap)bisqp@eE3?fM_ZnnlkbZLd`BGiSoC8vDpx0}OJ6_C zpva5c{iTPt-%1n5oKrgHNUR2t%GWQup}LvfsI6@Xpyk>)Ol{E$^XOyVKxYiYy6~&+ z2|~IJ%PFAe33X1$A7$D=Yx&E0R*<|KInpiG&)jK)STfXMn$tSGgPYr0vI78_O2RTD zy4_Rl7DgKZAu%Cmw&V1(E(MjC;VewEFe$Miz#odii|o6^T->Y_ge8Z>P;a22p)Tz} z0lQ8T54IAnyt8w+RUn{HFC~4HvzfK+)B+D^%?{S7`p9O<8*4c;zqQ($*# zL6JyD_mtQv<{ov(>yi%&!3K?gktLA3s}E(Z=(Yj>{4+uu?1o9`P*S=nPEdDtd*$bn zeZ-Th)bp^TH&bxje0sy3p!1-aCqOd8c=K=?-AA*XCgOY*vDQ>uA=9KzlU&kX>2b5| z14z=if}XL?;;iA=oO-Rix!N9DG>;LY==3EX;e^%hLO@v`4DFp@;umy}J}5-Y`Z zaR5s(l-wC{_eXR1OOQ4DlhH-q5N;58jyUkFNZ6#{QgfufD}L&3A%GuSP(Qpw=BX*l zTmm{wNWv-Q(pq-*Qs(|^XE?r9e*^~&OVUmahei*X4RW)BQ+}Gy`z;xH5wpUp@o#59!*sVAyW)wEs?HYcgdJjd8-QACdJ&(xXR211}+YSu! zK&}%Ei1EaCyq6%|5~Q7cLuPayBIFskU79Zt=m~p%Kp@5)<$$Ktl~{k znH)yrT?dQ}+65n^kaQC`dlr+1W^)9hgGIjsA^1j52nabAdQpAs?ymf57(sB$X+pt7 zMRoEKmGUO$5~ldm#@%he)@?*$oR?`c*uXJ6bxpCfwfH~k=KGAz%*+_n1^qTw_+nUE zi6gAmF8UUnTC4q)f6jvOMrTG?zw>OuD7S@q1->M(LU9GgJgPD{+x5BF9Gd8KyoVqe zm2fY9V>Ty59gN2I(}cvN0?=Y7J#KvV((u`8A88gCs7>qN4xAm#Z^@3O)9@+6m zBVVOJ!MC;DUPeZ{?Y9Cz>;U6#qP6(krN`9El*eP%$JN6)5RCTsDC5RjyBct>(d$~W z5Z_`Iu6-&C-Bd~-vMsj0G1U}bs1>7bM;aJkH>^f?60wtjLpr8)d8--0RYJIgwpAm> zCE;Ub#jnXJ)?NQe-^~+l08?xLbR-=C&?si-TH>7A~ z27w(;qeKg^PDlJuyp^YYr(6^+=6&oiy>)Qh?4a|S>faZqmzRVv1AQRBa6g&kfPkOV z7h%LR&_meekse|MF4+_VKE}mu7fW+(r75cldB`hU#?aJ=;)P3z-CL%VlM`Dt`H_5> ze~0v;k1|&j#3(0=)O$qRhaDYDOfk%M1qmLw#P}GQMj4O1$h%D$gJ~Cer7`>So=kB0 z=ymp50wp1o7=2?zxcZIeZhpq`NdxN^7Kj}%A9X&d>b(ifo@Ab-?}MswSk;|jA|PBi=6c0YaRE6a~%@zNVF^d^z!Sp_lIjRALTJM?2r zP;Z~}5n&=EAJ+B-@9$>W9bJ zw9+$1d$6QCPCA;0>3^=hdmgwi`N75LKAGj~#LP+NzU9ug>I`DOEB1Q5k0{#D*cq=Z z7mmC5#W#j_POjHcDi~oQ9srU1A!WU>t7k8f`-V??4r6N_!v8e!UDJn5ZB89U84 zb>r-gpzH&U*P3Eub`a~%w6}lk{P^$4|u1IeOvGREdVi=1fRM=D3-u! znUa$vc2dXq4p#YWJnYCOx)Cj_Jtmd9(Z%Gdy*R9~Wc}%LkV( z9US&g!yx{T=R%3d0+sasBe^7@gZ0#~gICB)X+fLShNMVr-G;KVj5s)~ep&JkEf5V2 znX9YafES`q_#A2Ch#K-w%6(cWHp@NIq)|SXDZZx(->;iPngFCqMqhs34Ld(XZ(Y3j zOBkI%0A!3{p%gi03-h8;;^XKp2;(Me<1qd>50J!Lf)y^IWBgcpzO)p{vCSGOQ4ezuZF!rXS}>{;>BxC;Nq3eP_o#H7k&Wdzxk z7zxlWizryR?#?f*RTfj$Va}*H3EtHbKPsB2O6bbR^PMieQ0O~%{SE6^pAVjkTMTCm>*Y>?GJ>Bq`4 zZ$WwLUtynJ$b=f@zxvfc<4miuKFb48dgV2ra!*Wgp^3g98>hCc$TCwqX`M+4@eov7 zP9}b|3alIef)9b2Q^A(<(p~ocMmasiC;JBkA!Waf!LCHt+`RgW?w0x>D^JR_@j$H> zY=ZXk2>9X+>@36Tb-%l3!19phJ7^Gnq1`5i$(~?;3VUCC>~2{r`@rZq(sd5HaYP`XwdVGb4V`~IW3I==4uZ06v2J} zo^>&)G4rgvGN#CqIxS`K7u1t&I{3JwG|{}u5|)uZ=-w45%b*ocvH^rU4lK8$$!BSBqRPb1ifwC@op zhfdH=X7i>@drLTYv)m%texaXBCmL!HQBlFOQT}cDvRLc0`^!-m1`+yDa$9_2BGN~t zo7U4wt~NL3CDD#wCVe(Ei?#6%S@~OM<&|v<{WSxBp|GRl4m*rc1F|W|^cwwt5_#5o z&ma4*N(BE`B}oZIppwJ9I>zVa+(MO;j5IE#YW!jWEu5SPLP%vGk~%0EZK+I1EP=cZ z_if1Od}Vh{J^`ikdZ<6g(+GKeKPO>H*=}wKJ*oMN^+Fe-AQNmd)%V{pb{z8@`*s80 zAMR?vQm?uCJ&*}1HLlX_?Cs#T+0*1IOr|o`XU;na;x_&O86LoO6m{Vht`%p@)56Fq zXez51FGG)>+KRW~NIUmc=OZfg?XuTMQeSMvgOlra(r&;1-g^YQm>ym=tcFJm6gthL_zdC@&MwMm-mTtG3F=Pz8p zcfM|_&yfC}f|Oa7$G-&|1%~h}I@`teSG^nky5djv9y%%a=&EoW*>Yb2&P?~n~Tq;yFpKr@(9gz#=s3)7K-)j%D<#ZjCW*7?@!j2cL+9}xJ>=3JdKU{Nik2NW60Mhp;uZDiZ_QdtpW>o|_trA?1N zdaFBd?^B74^nm>l9FlS~{~FV2ru1j>T9S}1G@IRysL-l}s-3P-Mi(Pa0w(`PQrgzW zA=nUctUf6X^oxnE7sbt#J2jQpEMg`0pe-xD&dOrA887EdKY8kWbF?!Jwb=q^!^IR# z4bd*sHxoE)yE{1M%!Vj;S$!TstENmbjX^K6zk$ksm9B1^b1aT+JtVt+KZLD)U$1MK zlBbMZRj&A(8uquo7)n!9sW^#e`N(yqx)w%?@|BREQbnAjgg=Eh(gm`&=sxc zG_%0jVMPPuC@|=eAB|WzCQMg-uf>d=Xj@6~kwS=zy9Af>6Ju&nj1x1CwEGKGLh(E! z*2nLI;M8anJ=gtc;8`3=T8_=|KaaC=9#|= z3ysm!1jfWt81r2rKAnX8f95|(=>CRxfv5amV)BN2dVKURF+qj;|B1AZ$!lg-}n`8^8FpmIW|dc{wmy!JM_GCKXvc>Ex&D< zOba|S2DovKJ09%x<_tk#LP)#*vH{jb7Dt{KiusADDikk-7?-vGkUe9PcMYa!HFnm< zQ=Tw%4VMU;be*fT#8E{fuc?t743;9pR1J*|l*?QaU$!gk5;utjGGn?I~sM5(VpxXZ`j5>+Qd&nCyjE+;?pbcd5?Dt*^zs0u>VyT>o@f6umGzP+LF0;Hd4NTfxCXZMhnzyCc}8V^PTC58~hxdcD+z{8%@Vr52fnVmQV zXPSpuYwMyTYWy%Bv8vn{f=O}h8{6G}u6DmR{j z$LJKaGi_9mx8*bgG;#aIlz@69HJZC#;AiD`q**$a)uSX=$`eEqo~yk1F#gV?nB~RV zI)KOun^!+g(4ju97*~J2a6R9@$Z#*iEINz}TT?x|CR%cmUpEL-AJUPkKT%7DppsaB zaSvpCdN6mZ)oG{24HtjYH|Y6|8t{I%%vWl9t$5^i!!+Lf>P<*L3_Kew6=n;TX&4=M zuD@drAYIOv|65_9$vys*vOXBW3!5OYw_$y}&tHk^gIk+w+k9V3cI#5D8z$|%Y!Zw` zU|ZNVuvJ4kw-JWL1&%X1k_>BZ^5C0vqyoRT8Dfr_LIYS*V~B5q+S^i}XP~8d66(tr zbKJKk^wlKp)&^vJ0pkiE4RQO+LnoYWt-`R@>*iq?ejrrY@#_X43~KQ77bUL;Tl3mE zCi1g)v)Lgj*_SDGY(LLXCCasH|O70!c5mQxt~jN)>#P^Y|jhkoo!Y4?Sjx&PLx$UopX+V+sc%EdX_5+~** z?YSEKp^C(VVO_zrI(L|C{7aX7SxS;|f!@~bDn2ic8Uik7vBc|N+PY@rkJz`LQ51bh z)tSJ(8E;l345UK6=TE{#o6y?qvzNDu6xL-;A4kBD?`6gwTrrL|%<`^?cQ~Tq{DY!R zxqeLk`-GK41*SY_z9>7mdm}2?6Y8NhJ$TB<4^vN*yrrH^lwee5T}#I+%`NqD>hX0!7p=$ON?dF2*WvJ#9r_+<{mBc7b;DM!S#^v78R^gdp*y6 zo`IqMJ&OVr!#z>EwcnThJlWtrSi$Sx+d?`<$^A_-%uzvyq0C{IQBQjW43~f20QQ?* zO(hjoHo%e%i$rBF4F`u7+c$$8d@!vN9!+&ttwmXaA`qE`g)jXWdFmud`mclRW|2dH zo3seNWE3A!+j>q0WMkHo89EGpu1_I%{|rrI_^&?VQj`;!^(O(WKJKQh36 z#LZHP4hnueSwhXmGO$lgPHUcSRklRgwPBu2qS47)dSv-=+mTR0QP}5yYsH$?;q4LeqGXcVjZo#gafX<8q1)W$@pT@HekrM zA~-s8!!wVC5>vhi+UHMmq_cWvQH8ztBPi0i)!W#9|lQJRJ%3FO2O?3 zs+C;WYCpdaOcy5b-ZeO>91#8s$xV3cKvlI;`XNGg5|U6MCD_*`J7A_uFZo=t3e$^nq+Kj-rwy zzk9N0w2-9Q%ENS;-Em~8P2|+2$x`Jlf4t>Y1J|4op`5U!9EI> zU#d&-Psw#7Qf_YpyDRYBKpsj&P4-1iG>~q{#j(yfKV`RMB_8S8$n(OqP0uvb@oU=U z(gACQ!9_FdkAHSQH`L=g-V#~ub}mAu;1_3byA0Vb0$NW?+5h9|oPsm!x@et_ZQHhO z+j!%S-7z}J8{4*R+qSKat&W}3|94KEi@jFWthKIo?W$d4j`@tDwQt+Cqi?x20{B#L zJ!7Rlf)wk)VhYziRVAObZ@s)j@UQgBil1)`qJMk;(_i+A4@4l%VL(7=QUB`?RA~zV z|2NP~x9yv!t)i@MszD92iGVE=I0RnYCx%c`OfJZ=xV?F`@Hug5kHB&#_JK759!>cL z0!;ebVi~m`$i(J6v*mo#?tZ-aJZt!)%0y;&`^>8GN%BV4M%cgF;apS6aJhOeR!@o2 z9vj=&674>MKY``1nc+ytGL;Q-sc#j~;i(8~v4W5%go$jB;ONxewo2zBmPd2h_w0B1 z2@A?|as5af=qN&15+3&yqRg;fdAZCrU3KFrh?!2`XkK&Cn(h5vZ9qb*FT z3cV4m7Wf^FZspT@W=JKl%{qGs=9NbejhZ*9OP%C7F$s=Xzq_@W=B!lZ9%3OmKN3b-`A6dm=yh~bB!%VJi6hK2M8oWB zePblN(?>tJ#YyL18L=M{J4CF25%65USEe+tN0h~*JF2PdJ-1gzCW|?t-TvQ3^pm%| z{!>W*6LPAR-;&n<2{{e_SI9X9@Brbw@y(irES^{z6R+qplNgK5WOO^N8ekaWT69%2 zv^JYEo7fS|-t*+$sKytzv+MXaImW(O@_XIZJr4rcL=I0*h_KUfU+U|BQJ} z@`@#|t5%`SBSk5MmRs}g*@SFnPHa4CYZd_PEv)pd8x{yOJnPz@8C>lfDN7AH>FSh! z{Oqr%uqng*hTR5BRM4uLtxO-a855a9@k$46Zxd3F%hW}j(^GN?G=U|r^3K1M@siBs zrd;}?$SB=Kx)Qu;8S-dLBpOA=o8rnrP01vuSSiuf$TL=^M|Sj4kOAVp$uoub>0N5> zrX7CcX1Lv*ycT(`pmsF+WecdVNd>MG>Vt><=>oU$=tE_+1&YfpsVR%F$tm*}M#;X| zTKPud%eLIqSdq# zx@Ha@id+_9|DpZno}FV*K$i>fR5Rys@(};mGk<1;z zkIIrg%v)ah$yBgjguF z?cYaO1QP1nSqc}me0a?bi~tzAhCv-QrQo1^4BjdBRUm018`}7YG->3eJG$uOsd*nH zJUahRZledNDG`CXtBM+7We03a=%5X?!Jn->9NyY;#}6Bj!S;PHjskd-507c~70+sX~ z&?5!aHDHAq6iJPID@o<1=5!0pwX26D`Ax^4yT@!lEYAiMN01W;{Qe>nzN z#iN#KY04{8L{j$!KJ|{kuk3LmdL)zg%TD!<>>UPc6;sGnh`8r67rO4$^0VduW6#PR z2h+=6*W-^EPi7sNR&uxWiZ&(=X^1Rh?GV1#D!?_t(w2k;S_0r;eAZFc2|)RXSC=^BG^R&nCheEvvu~{~dytLH!ARF#||wSi(e_ ziLr*^JD=bmgatM0pQ_5(BR^aAK=B4!285^`Tfux-->Q?%x5!@*=dB^yo=0K|yyNYD zaP?9=J;xhJ<+D&bX$2nx=F4y_Fa)#DECFVmzjW+-#b)8`dm}-O9qH1VJ$!zw+whzR zP@nuNeG=CkGTf3As*~G7im!mf&IbeC8y)_d+b=B+TaO|7TvT! z%`ZO^!~9-2x=%1x+%x;aIV_JeVAR~L7;?a|u1m!6sq|**_y2hy< zWk$srgt3!FV5*s>x?7_ZHF`wPhhCS7Bxjl}(^_OjpL3dlyFEASte9w+Jl$9@=x-{f z+gtA%dd`_*5LT^nJq9NZE;{cWdLES_SQEc86L{nz<`BqHWqU7O9qGkJV9IBL-i#bh z;V?ned_hH)rrAi?-Utc9I63V25-cq(4=WYZ2?i~bi9D8bD61D{4%qXXyWWT<=KzPQz zwz*h;vAaT`Phem#Vl$fA=33xrj~wkBxXkU`DPV$m$p*j5Uy2R_EOt0%AmwZcxO`y4 z*nz|gtjZC*JPJbyTQ?Kg`=B91xG@4?(i04t;|RRS!ee(u(r8PvBqCBu+e%-eJ|zp{@O@yUi_Gw)cQ-9{QK3KJ5*rL`->qMYvOM~5X_{MJiEpAV$c5i4hZ%p7iCv=4Z}?v+S8(!?%T+1rdqWNy#Mc9S|fYF$72;fz5>XB?Bz z2=~2RvkdAm$rIsX5CR7ME5xHqMdWc2>cmk3b)tTKCHDJ@hUqi?pxiwvjknC?R?u=bXra||nznZWAS-?7&{i}64i=F8V zu6%KhCL=lQ(!_Q0bVv(EPubn#2gN2`6&?OkY(jkVuiC-cTP^j3*GgtlfHS-kIE@Ho8>Kc&gGSlt2AZOXi0Oj+Go? zW-cCjMq?c|a6^$xpr4YI#7l(8kkHgojwXa{_Ggp0<5}gKDL(xj>W4R#A6=(>Nlhu7 z;+ieEmv#nUDBs#k$GL6NAL*+d<02o^R1s=WOWknEOVaBpP4=QVfx$^U1-DEZU%_R- zkqYJIycER?YBVf}QoYHM%jGJwMo?(=XPd8R;ZKIegvNl0sCH3Kwm}qWnuTfGqG7?) zFaPhdyPH=fdAu(oUs|@3M2MAaQQd{HbFGMrj>B71x4yHL5bW(Lx5wHKuH^3lrqn6C zPAFr}q?uka4b#L9LGl7%CI~Qjw(J9l1k)JF28r}2i%LSk&%hI5prR?LGjK?X)pOuM zfx{Man1a5>l76a2juG4&RoaRh5?+*t5bi*?f*xb++Dz}MVHGpRm_zOq!VT(cpo{Bh z#Xyl{5)shgu))#Ju9Sh)nt+LJF*TqCMaNBArm9?ch_>4AKcE#BrUjtxQKttc4pFl* zWJO^6lFx^m+fBr@#blxcK4E(3(Cg>Pp2*2{Eg64zD33MNK8TIeuW8Q7VU?>U2bG&5 zo`*oQZn`ZpRbFb~x9I^$;KTkF@zM#t_4UVOP+aB^WqtC~P%p!}z|+YY*N2G8Wi2_K ztr2fHbq-=ZsTTbs9vES=&PM=OEvMnyWvt_Hg9(|BUM9AJCKqra3UeL>3goz;5TrZG z;g5XSsFeih3ZEnS<|Q*h5xeEBRm(*Ix=to4uoQ9^@#JV{gCiv5d5>n2Q|q-Uav`i% zfiCT|!4&W^HECfIwJyQXVYF6gYNMv-@)1lH9j;RLl^n|I&PKYEHNrqreZ3q2FBqMc zsTLM;eE6Fux3yTRmXDSYiPkBoIH?;O8$rV2dlXI)#XR#EjnnQ{7LIZZ3w0;kK5 z1-FtB5N{;!Q81~dAQ)o0ccrCsKXbD>KP&BFV)*m4maT%_$UoTiw4mX(#1=q3l_EOF zhoThb3Pe#X>~XLs3UXl3jWNLW$wne5(6J~D3`M+~nq@&l{xSF*Hx2*p5|(0#m**Bh zhKe}g(Oi$vjwt6i6`8J1S`GDcU^_&)kDdi?oW4$B68w!#k`|e5-;2nU4q#o|Hpl~K z^A2GH6~SPhZ*z*Hn7J`OUO`7d?|a&8>4KLs+j{Yt8Lh`_{|DG61Nhr89FQJ>FUEJ)FAtTlvB^D>&Cc<2e!OBWxuD>VK9E**NrpUpk<{C+gig`9{PwTS%-;vD!gmTpn^rJa+*t>~LKt~_({ zdDqV`kX>3EqEBW)*!Q(s^$A%o)XSsv#}?IZ8RWAC0dVDHVDtIrozp`V7Xxzkj;Sh4 z%tIye+3*|H_GIv(u+s{~5BT#(r&QU`EMH85;%`9=P+a0c*rF#o&$nU63e={d8&ZdR zF^CQ0SU=#Mwlded{=vh~r5hgY*9(<5g&g19QlaqfQWBS(FQ+VT2@yL^gUk8UorjKo%eH@-b#R@0Udd@CcVmFgoGvyi4EJm6E?9g1w1I3g<`)VfToctQtfBs zod$>{2DYd9-_G$HaJ5T(ljh%9*B~c_dMfFY_gg@;%gOrz85=c=@M@nf>e<#xD0p-o)g|o9`+2(4HoXXOQMS2d-|9$L;~lfn_)(K3S_$K3&F1OhRVgThzXS zQ+B}L-dijq+1wZG8j*7W(u}(=+i|&~f;)mE+l`kqjhcFSq@rx-7`3i~J3JEtCiubd zKl^WJb@qJb?Z>n|1q#Zk34Gb3?l?SGV)$}!Pqf(qLNk*Eh4@5A{%GE1Hd$&QNXxmq z^z|vTE z!a0fUkIhn$%@NY6_A6DIHq1Fu(!HiQcm&Uq%TnwWvh38+#(Yv!yrqT~Y1SlE{;UDk zS%BLIBufoNJY09wQ5|Z15Q@-{Luc>K%Fm(3lZ1(s24tLo=SGAqlXArV!9Y>1koZY= z@tM;>6O=!xIx#8@dKaJ02L2^IU~q!1L?`jr>kOC=f$R33WYqq#n29=I&k_-IUu1^UYC zUhLOhrsfvx44jLuc3$UKAACfXVHh&41O^%&y}GB6ee!I4qBBSo1&+|Ybo%88a#H?< zF5mogdWL2ak2nwUndNWt2@>#qW%ns%Wa8NqoC`So5#stmr)0F%Dp7qegCPneCK0#m zrVv;7Y-6X|;GmtZo|Q|UuUTa8{c=2klCE~II>RNwa$n9Z**;L!Z~=lNFMC?4q~5at zP+gavqh#dnRgKgEoRrl=<9UP=a+USEDAC;B3lsu^XR1}TgAq~58Uj(R(ZBChCrg8N zs*bK=c>S8IaT8mhlc$YxI+cJJuJ8vhMT(Q$LbGxxxl0UHmozG`70N2QXqLW@c}g2r zr4qSKHmGi(eQa=jZa?-C-D+`@pRzIr90j;zFnMw)$9wiWg5jrZ6jd;IL)s&>I#Mtf zonU2sW}vdEjx37XoTofDyaW$EYCJkBw<5Qt!nZ27DyvTb?rUE5E)Kw!oXqX)YZ3l` zgsT+3 zy^tIBkDM1W1=)vr-G}4^0!jf}>`^l(3a6es{st!osxU`Mg0co)e#dix?5R1$o)7rb z7Ri{uC^TeqiE|&QHDrLLWdN@POx~0^&lnH}rz+y!!ju_z_W7Suc>23*GIIEVO-u15 za0IQ&eU5nghcA%J+y(_^ick#h6HNm=u?8nqMaeV75ZRCF7hOr3JgchNjlt*HT54mS zez;jI)-HsFk=f7l)+f-_j)Kyu+`V$CyoLpnS+&Y&lGn{OM@_mj7zK|tku;a*MF=$n zF70#@(=~%l^BnS8Z98(AdPu5~oe_X-oAPNNtme*}62#~GCY>Eo-NV*J%~zWxnqJ|} zLm?3@?Dc%6aQttm|7onF8X#g67$6`MH2*2;qmC><1aDmpjPE~1)4zRu-Yq-b-DK>veN2$6 z=#1V4O0r>AJZVAwuDGZSbZeT8z>YB+^;Y3CUGUh7N|PKY8aE)@gL}&8j}A9wSGl@j zA%$t|>0r8y#Pt!3G;`tNVuEF~FKGTtvHmGAE*%7k+8yG6Qg2RgJ1oy;KRm$RF&;%F zjTOyg#a&|@&SYv|(W4%WJjZ)!%5PcIL|W1Zgy$o)haZhr9EOu5N4@`(SflD#=xSUbaJfZ8;=Lz#o}+Fvt^GoSL#{; z)nJ&&ss%K;aZ*t*wC7Sr<7e3I#`R_21r%$O(^})QW?N|v1Zs7yhv_ZSg}cnFwqM(- zJf%=QmpB=@wWMHVBbCFP2yi1_Z7L82K981JexSYDbi~M{O&PL5Y;kne!Z&hIm!VSU z&8dBqEYVxy0YeV6b1s4cJVDV0N*e#U?E~d=R}L>ns!Dld`s;Cz3nh)t%f=8xov)jU zFksRhA)0Z|wYx?4H=@gUb^;!pP>;pH;B1Pdo#B6y{4ku(heO)VRFNRXG-k2ki^+1R ziVpL!vH^5Q|tEqN4 z#l3xT7ieBfN=MMJ%wAyHk6Xn66or~8=G!sRjyK)nkK8v3qA`=brb+iPkWzUC zOTsc}IdLc<1L9)Dq@Uu2{i2ioH?Hc$oyS((K8CmC;87HqJsCQ#J3bEbzV0KBch0K5 z2oLiLCWO|4r*@2taT85Akak3SGXsZ;uVx@M;;)3B0wMu#?Jlk?Y(?$WvANW!R$UeL z>OL>%Xd3y~8Cd(0u{c?R*4sOWJNFHVVf6E!@6OAC%e?f#Nla5V4X%y!7+&Gew6r!E>dtWD zg16gd(%)(>{9!05z&m8m%w;b?L+NN#X8v*s$;I-Zi{g6winbvu7}ffjR6{eP$*&ny zh}a_@Y8`3cf;~rm66H3xY1u!h7)r29F^p63j%%t9O(9bCp^m4!Elo1%uesK1!MXDo zBsBS)=N~Toqa>TbxrrM_LyB`_Ol>%8!G;Nu3~sEb6%p%-KnO=iFGXM zvwKr(P8Rf!i2WR9uc>Cofd(CpgI!DSDZ_zDT;J$FQFJHka=;;{FWnxVUNmF`S_6uc zv7;b@`^5NKGe^m5y+yp%_r>aCqBhEO#S)iOkHEq@A|QF@mAF_GFER$OAYmpQqjj7m zwC^gd(3*V=Sk!vkBFS-{Z5u3ifJVjnkE!8jV>jAwoy;c1_hw$gII4oD&7(Zra|9Mnr{$n#$Zr`kUe!Ixh_5#P#1Wh8F!bdp8_0;{bl24p+N z21)ED{p?{MSVZ?EbSXT}8gqk28>fu0=&j`Iz#PRko?@@F?feMQfoimj4E6jt z6FtW0G=j!415Z1Nc-!AWBYxf2%$2WphL5EXfrx=_$_Br>G|`jqT4$SOzNNnI*9_rsV9_+=zTa zYG{q7Kp_Dk7NHW@x4VZi9sgp_1MED3nUctbnRihU2P8nFa9@pLZts#4vh;gRpN1-?G7iz$})ta%J`x4RV!5)QB(1 z-rBJA`w6Ei(3>`sud!@S`>tO^3^#NmFIj8F0IdzPqj)rz_bO>0D*yp90#_$Q`MukOYh8nVF z>K-q%!qs3}B;A|L4@^RwR+O;}=R}!otdDUNHxuXW*?L0A#M{)R6^JA-gA?Um1R#-@ zfow@TKNA+@96*m@vMT}7WN`-- z2bRh2Emd1q$mN^S;aVy|eA0r^RN+hN0(YxKvd}F5Ak6yx{<-~mN=|a2%B%|Qx&jG$ zVZ~9MwjvmY^98zb%!EHw<@ZM|SJdHzxWIRKyUHsg(p$9yP-7pgd2^3h^eeuV8NvcD zBGj?okU*I3J{98QJhAAakI%prJQeC=16lC>mveom4%6yn9Mv@eo^WFJ9K;v67eBdg{;1xqSYXkuG4M=^2C>Bg zgh@IT&c|#(!Z-X0MFsixa_HUPueFYDmk})|CV(~H4W0A1YC+r9;xY?4Wr;YAnS!kR zW(4?Xes^hr4@IEsscW20uZN#wwpbn42Kq)=#Knu=I6y_yz%b+;0 zKtBof{*2zxim1=@O`{>t1bA9Fz(s$qRuCT`oONz;z8U@RFT*wowsT^rz%g9KP&XBI z)P3R|jnql8^JWKS9)EX|nOt#g_|I7(0~*yt_xr?j?2^s1#6--U+Lyl>Sb+(1sL_7G@xb#Pl9G78ijyP zRSG-p+fd~`x?_Bs>_X*mbAka=i=0;@cFF@uz1BkazGpoVGE+n0vsn&@OHgzuIxA9+GSh%{`xftn|Mvwmm2AUoqFIo7A&p z>c+X7PBHcYdexoqV`^Y8zczYLW-&)FKQ&S6+gj)~-D0u3}p~ zBE-WXQ;~ZKlol%V9}o<8lrmp%1$rqK|0>3TG~$A^Q$UDJ4M*B#2M9$Cv8=vvQaj@? z`m=RXCzEh6Us(CIfxNRr(5juBfIZB^_4j`s8%3BnlEEW55Rh+-|L3v6O5AaTPTZ-* z1DeHe{x1R~QunlQr&WL-_E;Q*&+^CEjBAjSc^=+ zthbj=Y#PcWu#x3&T-mmhvnvN4m*iuOFR8UlIa`zx+S;?(;0oPe)vVC3#XOvE zsp40pjg@hmHcO4%=~QuXws7JaM0)+>XNcx`r@JT!OUWkoIsFtBVs9uO?`30E7=NLv zpDtRF`}4}&tBo=Us>ano<->3=C*-iB9EZU&;cIv>Dl_DpSPCXd;d|XXDyj>l-R5wS zT$zXqKU*|Rouuz&P%C_=)m-=Q+n+ED{JuR;7B)6}obV4EXN@T1rZ%>PCoAKnHsP-| z2M3pg>-(X;Qd4Wl-24@Fw!vne>-PhIt&J}D z-^&os;RCh#=YTo+_bAIHHYZ^xHu^CEVLb3gU46wsz}o^46ADaE>sFI2{kf$HP-w(j z@Ch3fPzumhrHsZ?Qu_k*VAjmsuo5g+WjDsGVp^&3&7W)exeP7#l@?ftpe!p5U&< zj4^8-sn}-4sNwq!@vU6}$s_x1LLEW(<=G`cpzjmkR$7#mr9d>CZ*aFp? zh%*B(H8BJPo%=YSE*EG&Py>>HD3wN~kMGf0jF#DEv92-e0LoJLociW)nC)wPW&*9r zqmM(3rt=~~TNVdr$!5R`l}(k>#Q1gqD9%MxdSg>mUUW0~ z`{W|Berc}432clb;Cwkz@gkC$0arF4{ z8M|cf8s*{F3+CI7>L4Hyio?BY)bZiN5^-`f7Wyt|GZx$mqFQxKDLTLnNaXciu9LsK zgk40;;6O}N4WsIZ`*P7jOw$zAyV9SXq1Wtru~Ho{Vr@`&IkzoyCO>$7I5;72wtj1>5m69#t|HLGbb&$d><^omVmuu9`6V%P6P-wpk6n zfG6tKm^+_k%h&d+J8(%P+nexmnZH#o*3QQ1w~(EdB~+(F`rZQ&k29(6a-8^z-fA79 zx*48$8JK4#lHQ{RQFRtXxwVkjlFO*ZDh{ril>ywn^WzZYX(^Iho** zv!uM{A2Kol`s zk{yGRH3KgDGYuDe_iAQ=+~y8@Xpv`fKJWo7iwNHfbRVaji4$Dz5%TQn0WsyXKVn6L z>zV<(9o{0?oz^ACe}S8d#czp}ZKTtPchyT-NEZNXgsyM=@ow)GD=H*^bEF>A(NBQ1 z5IgrHW{+qXS!{UdlQZZYvzC!AKw(EoXr{wkSlQbOiJ|^Ztm}@Z2xYb6w1ZbqZ8{f*&l zoMmkc$=2F-oF0y?u`f5^XRRSYmV|v}I1jQj&gUy9#ie@v2M!yWG@Vz;fzm10<0uOW z+-*)zkAr6I5?{70(?nFmmM7FQs4=&ri=_s-Uj+=(pNw_X1~RP}`lJuKG3K}MU^Cnl zQdTE~%MLcO>(Hp6B>*<2a+=^m)e$O>!pTBR+Roc96uHA^Si#(waZ==V+JCkt!jy}1 zsy?p6JjEmj*TQEh+X>!23AdP5t3W0Jei;!eC>$iT**9CtySnJ}N^t0fR{Ly#fQSGc zg`y*z5p4z`7CG*Ctyz2mR$tF7u!^2N&n#v0Pfk6Pa42r`#mhv#`tA&rj z-XY$=2k#O^-aOwRAcnU}g;5~xS-_^8rKYF2M^*1>DXLDr$I_@Zw6xGWCbo`N6;d0s z^5(jJTGi@|U9>zfx}=rhqyQavd^Lciz8xW91NWxAW*5Jmy$Cx=L4+oYCoN8SPe+z! zJC4GGN%%8~fWf}W!$1U2v-p+Y`Nu`MzF@dyze3}#10GPJE>BL)kS7x$*h8O4bPp_I zG-+wlK!9+|C52{YyY~hG*KavxFtT5qJ_h+(r|vJNOCFD}YGprut^Q$PnM?%=hhk7Y zU^eK)JcB{B(lUMYzLfKs7K!qml3;$hX)6E2n{2uy zPfpFMw$0|ww;~UiB~qI9D_JZJx#^Q z2S(F2%+eB{wiU#ITKj#ayy5`=?jC6)&i#Qyg{}t<>8E_LQ;pg`xYg{V9e?4 z$RsqRt&`ur;^*fl2D9O55rWp_*j|A1)M)b&*$#e(5f)uyVFXb%90dnXwE6u@SNqgZ z$4B;E;%)WNc#{A#n)MK{#S5@UVwyAe<)Tgr&m%>z_ZAt@Z(yyJZTm@)MXsqqXmTX* zSpak1xw5xsx-21=D1+YyXreCAsY>sqKf`MMQ6R05bvCs?h7i7bpU<0!rvn(D~%l@=BWb zC`=44f2MctO|f`}ME<6dgUDHn21QDIp85?#+T;ScPY6O(%s$w|-V`?_S9p7vDG^J0 zjn=Jg#I5JK;bsiFETa4nNW;>&D)r%jfublnL(qs)_3^blEdiX;!A8k^f2`6RYft{_ zhnRHy@>?5q!_NYKuO@$ANcz?j@zknv?-3khX7xDgsi(Sr_V`>zgYD;$h79TUnKl;B z<4mhWx9hrt4~2==F5b_DBV(W=OZA(!c()NW1dtB5`y>kU%xO;}G_b>k9SG~U@5-0i zk1tzu6BF+3cS@ca5X{Fqi62xSkMmvqh{r^4=TNuMX-Wdx1R-`yU?y?np^{-XSVAN^ zlhgM7vx(AyvFfF>%lnkY5iMVdbz#_vY2FTQ5?UYjD(+Rre{)i75;I6$K*4Ly$^JT) zd1w*diFETJclFN5sF^=s+GTGRuUXhQ)qowYS$La76+~$A=S;y2hpHvgY&9r6s@Z&B2T98NWk+3R=E1n;^t-8XnF5C~1D$-*3~zl#Cv4wIL)yYMiC&Mxhq@(`C=A-zH6f@L=6UG&oI&cJ?RM%n%pH@!TFi&w$HMo%Ia=HKi*lkTN_ zMdcUJ$~q#{J16ChR6r2IW-%0Se!*D3-iwLk8R=3ZEfn;4Qtz9Q^WgFd@cw%-t18ts z+*%lKpOcyYT#TyyVbXTf5a+(ULh5r%-7-2C8k_UnPhuGHR}f28OyX@EPMIcyc7cNX zeZ43*I)OLm){B&E=QNCoQMcF4)ifV?qFOgQyB!DE@`C_a5?l>Ua}o*q}+EC5|uN&^; zkp-ahcePTDs~1NpIr{ni@rV1sItoFMLsnIQGbk@pAi0@W%h`HEYofno05bh4NJS>&zER?b&t7s&{% z(RDY*LESctrPnknaDEN`bNXmWncOv4G^*(|yu?9q@y`#EKIKKBT`JA5FRBj^S&6sR z2Fnle#a_Aj@AT|;|3>Jqa;V>Ix;{`Sq)Js_!s+cp$=c);VxG(Z^qht8J~tI$UjmUm z=3{YnQ6(b*0}(pkJUuA4m1Grl#7G3rQf|hfY>E1Ioh{b_>YrLeD+L~jA6JYK;sdMLA@|Q%!`=EjA=koUt*Cdy zwQe z+@Wg1$U|1BC0Ow9M)?^;K*HTmH9Nr6xN>peU(t4GoF?q{al3P@F+)p+_weT9gbpJO zQKT}4bsaxpFZ%-hsWWLooeBB8a4x%@<5KIljaJS7GSkC~B1cc}g9{!2?;;APN!1!$ zOaW2bWjn7Fu*_St!CfB^wOyF)A|$wli9gk`8+^cfrWbYAPg343&K&D;eC)aMzTLbO zpW2VU?jK=L|Z z4}xLeLz;0s%%g#UY|uKfnTW!m$l($w%T<8UZGx9`i5)XBuV+}RZKI@(r#btwJ><%R z++3`(NAlWofEFC%;QSCb5Z29YpzqTK-~hOk0SSYVrMUvgn@)od68gN6H%bU5Qsj<9 zmECyJGama|XqK4CncJz5iqB;Ka2j$vk411qLCfb#<+AOynl4fx6oL*yg^K~}{nk*h zJuhdF* zd%6$c++?+#6A|r^Xjbk1b8G_yJ=Pd2mS7ao>T!oyfo#y#1w)|I67!)aqMi)Zd)Ytk zn{xg>c_XK;1fSGfRuBvZUFRk0NDW^tx~(2i*~_p-#y;RGjhK4=nfA?=w!5=CPhaB* zws7<;#G>=!UtX)Mgy<>%%pROWsrwaEZc@~{cYFt9p9_=vtCWiVF{oX<=2sV8*K^HB za3E;qR_rYnz3SR0VM`Q=y>L&Y0=2F2U-02cqjPk6geSTzqa)UlR6muY%(wq~MY|+-`=@dmpw7VMKDWM>RVuH?1vhi6%MjpcLH%s+|W_ z#pMFelu2|80s`baTs>w!CMANy0mMWF0s~~VvzfYU|8AZ8J({wFwu8X?%^Mq}L9Nh5 z08%z$lQCVW$U#I82$^L#eCJ0j;H|H{3KdVga{IH@v>oPyJc0{H4u!tG_U@|aT!+TbeviFJo@HJpIfOWq_?$I z!QhrEGa~Q%?LTusl4~?Zm>;R;)#Fp^sSbuSt9SZddf>t zTYhtNlkv1Yb-l&?p0l;`2sLE#|K+X#(TeDunaq-c>yI_)3~al`7?j9O?EfL8?I+Z+ zU+e2pOdep@C#HIU_0~G%w-fvvqEg1G^19Gg8x#pOaAzv?2^JwtNEWIP^@Q&{;3IiV zyc$+vx+N6Y`!V#zatT=U@jG!_uEFwu;t{*O)jTH5Gd7Eoa6#b-D!sEy8SGPm3-_-Y z#xJ-5@D_3dhFcHbDpnq>dQlb^D>DtngOI@H{jN*DMh%F)gv>F||P+*x$=d z3g2D=m)p=Yg<4WbjLZ-07ThMlP7UCEYJe7dS8+izy0*KIt`rd?D>!{97WNERRK~|e zODeLO@f(gJZpuM8^p1xAJG1awv|eeuR*5S6kSlyeQGm@)XO)-gqlB;t0#Q}}66_76 za`vKfjS?pEXM*ux*Ks#fIawf*%(x@(ZBuie>a}~Yfs(e_XwRR}g5tk{*d}Aj&73f0 z!|!DZ=p<8)^3jrl3R;90!nXR%6O%c0*8=SY&A{SGaLi)?HpSzrOr?U$H4Tat$MZq(^=wj_W-K8~)|=>DxMhPc1CaNd2)ncn`f z*n}oof;B9M$JQ^vCg+Bb^ijTAwTEq#8e>i_!m_TbK|pALO028L2l^!1 z{X^j)k6PrgH(*Cs8GX4>tw)$Hm!ob`$E|WOUMzT4Ezj%(#1&Q-l0L^7&x^GAN8J{wf2Ea@mR+Y#? zlLJ&U(k&%%aOf;fz@NC5Fk3Uj12xOz={0oDrYx7>9ot1Q0;j`WX>92>8`oWE z8iN1=C%4HV1-n5i#pCRV>9pgtCLL9>+`ngBz*Yxdw>}2E8FkE0_N9oBLB9f4=HxEh ztC&Gm6jD_a6enTj^iP`%EWFOM&A2$4N#zi_n=P0;puv^Scob;VlU08Y1JyKHyXTaI zsV76qCx;5k~ zYFyias8X2u+CCsj7*J$O5jlkL1MGpyJd^oi=!Dp6RLt@f)F<2l`SoY$3CU526#hp( zo#5H7mAm&sKU>X9K_FB6K_p_1>u@RlM?9b4(Jqgc_eMWa=fNUk4?G>?%ajFQ7pzjp zEwtNc|LSfz9HHy2McsACX7upy@IQp7pZ|rzt4_2@-++REfhhmqZ-OI-3;6DiCV~DH zB8V#L!Oq|?haKEvwQw5;fGunC(|jwSF^cfpG)-XK{uj2OpeuY^o%iA!@FFgPj)C5S zA?|yN?|U12=V8HRmB9JFK#Y#PbIw2$C z0g+(OaWUAMHF=(6f!)lWnf|Q7wV|X+{H^4;m6@K}l1CAXJEH*;#blu@#>QGzk%irD znoudUI&s+!5yG;vYT~#M{t==0X<~G~EjGU(-!T^pu5Jtr%Np7*2HoCTW}N{#}RbyDvOnBu>K51gd>X zLWlH!$~yOWsL}?GAJgPgOj=Bf6S?0nFCt_tL$1Tx9d{BUlS_@Z&|q?VZNsn}rkj*P zUe}pyB=Ndsx*$SXYHMm&O-xuNtBXBOKEr9}^O=9<`Ofb-&vP!H^E~G{zn@9pqn4sE zJLBMq8a>IQQq16uOP4FFX7NT3_tgO-GCOYd6I@;?x>dDMU^2&dkvU7 zT|F2dTwIhq*>oUDTkjjKWe2Q4;|HpWyJMbpH=W`tIdvCbw(EJ2yRL;A?Sr*WrTD|7 z!Q6L}o2B-K6_iz$kpo9!)s*nwV-6CUjG_s?WXqg5F}8Yy;Wr!Bc=3O@Sjl-T3HQS3 zWcGj0s0=9lq%$ALAsKrHHatAdFASy1538neIl-9^2nK0{JK(W!ZXdQMeOqe@w)8Z= zpYA{NQ!T+UHK%S*c7@crfJ?vqsu(PJukuW3z`ILa&eMDBze}~{OR^xFbSO1GqVM&= z4vC{i=ZnJQHC_9&tVbt2+cH(bB2$l{Fc0?(vshV@?Tcqy@VxDR;XHZUJ=Dc)&9V|I zWpJggWa7BZV{rIwfrw@QwOWeukcZI^-{R?3Cd3HhmD6L4tp)OeIfZadXKgQvcNC^L z)X$Ff-i1-}i#tJ3lvtKCA0kG4ChABWW7HZGTz7^0lw2n5?WK}C@(YfYVL$ngmPZ}S z<0kb|eD0fOTK!sEI9qd;zm3^@VJhykz1{-+O1_{WBz(l8m3p@f?cL(OG!?RpEh$4bn}NBXooR}278UFWGj-+hEk~a z`D9anC^ue5&=r`aRCvfGufN%5S4Kir4XafnC^7#wK6i*<*pZ_@;X~-iR=Sy=|5rhA z_4Qc^qIb|x59^bAkokq@`a4@3DBkoZizT74Ek0hKlT%cJQtzMN;N0 z%|%>rcF%p?aV3i?w=tDJA|oX-a6GK04SQCsxILrPhg@xV+~wW=VPcT7^u*RFe(sG| zX})O+)VX0_=JkbG7f(!~p>%RU2|@JqbZxU!it-DjCW)+#}uPX zt+{|G%#}Ammq##B+=!beac{@3ZV`)35?5;?AMRsusdrgd_#w{H-f8sRI^tV3K6o)L)dSNXaULi9-sPLXlUf>R zbiKP!{c{Q4=S}@LJnjwMI=JF8~SY2FRRY`wJD~5`(uy(r>q&9&K)4Y$gwzCJ{}tiq1oT~{Js4dpb|w%m zZ-Q_7Oi|@-GKkO#ycpCiqX>&_RTM^?1Hf(+D~(@e^;Rkc*XO|6pg@kiP_*>QPEZ*3 z3D=HR6j2d^%Bt#!>RL`B0H9Sn)r9cxaPB(13D}irKB&D4kCD<^S0)NASLuSnAU3#9 z&}~-ILBY1Va!Acc=oh?>V*u_b6I6Rxdcr^4(pOl4HzJ8mkVv&0rq%!{95ggURMuin zzTOoq<5d+=IL%2JTnjDu8Z6%lO;y`%M7;K)|J2A~Y^>lPRH1`48lcc#{9k)=-WsZ@ z@l+I=Tf@&GQH|JZ3zsWG#ZI%-NcA%6bl3@UZ?AXenaPkW7I%O2(pMz|dY2laS5}C1qkIRGb z7kzS1F%j@3TOa%~rdt`(0e~S&EhZm<95`m+>P;?ukNb6>aUlfyG78iO*I$;jQECdO ORzXA2f%7X@nSTIfr%7r6 diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 78cb6e16a4..8a848873f3 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,7 +1,7 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=bd71102213493060956ec229d946beee57158dbd89d0e62b91bca0fa2c5f3531 -distributionUrl=https\://services.gradle.org/distributions/gradle-8.14.3-bin.zip +distributionSha256Sum=72f44c9f8ebcb1af43838f45ee5c4aa9c5444898b3468ab3f4af7b6076c5bc3f +distributionUrl=https\://services.gradle.org/distributions/gradle-9.2.1-bin.zip networkTimeout=10000 validateDistributionUrl=true zipStoreBase=GRADLE_USER_HOME diff --git a/gradlew b/gradlew index 23d15a9367..adff685a03 100755 --- a/gradlew +++ b/gradlew @@ -1,7 +1,7 @@ #!/bin/sh # -# Copyright © 2015-2021 the original authors. +# Copyright © 2015 the original authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -114,7 +114,6 @@ case "$( uname )" in #( NONSTOP* ) nonstop=true ;; esac -CLASSPATH="\\\"\\\"" # Determine the Java command to use to start the JVM. @@ -172,7 +171,6 @@ fi # For Cygwin or MSYS, switch paths to Windows format before running java if "$cygwin" || "$msys" ; then APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) - CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) JAVACMD=$( cygpath --unix "$JAVACMD" ) @@ -212,7 +210,6 @@ DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' set -- \ "-Dorg.gradle.appname=$APP_BASE_NAME" \ - -classpath "$CLASSPATH" \ -jar "$APP_HOME/gradle/wrapper/gradle-wrapper.jar" \ "$@" diff --git a/gradlew.bat b/gradlew.bat index 5eed7ee845..e509b2dd8f 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -70,11 +70,10 @@ goto fail :execute @rem Setup the command line -set CLASSPATH= @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -jar "%APP_HOME%\gradle\wrapper\gradle-wrapper.jar" %* :end @rem End local scope for the variables with windows NT shell From 01fc964cb63e1c83c8e440d00a37814d171d8892 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 20 Nov 2025 16:36:32 +0100 Subject: [PATCH 002/113] When handling a plain text share intent, check if it contains Uris before handling its content. --- .../element/android/features/share/impl/ShareIntentHandler.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/share/impl/src/main/kotlin/io/element/android/features/share/impl/ShareIntentHandler.kt b/features/share/impl/src/main/kotlin/io/element/android/features/share/impl/ShareIntentHandler.kt index 9c07b588fb..9342ef60d4 100644 --- a/features/share/impl/src/main/kotlin/io/element/android/features/share/impl/ShareIntentHandler.kt +++ b/features/share/impl/src/main/kotlin/io/element/android/features/share/impl/ShareIntentHandler.kt @@ -58,8 +58,9 @@ class DefaultShareIntentHandler( onPlainText: suspend (String) -> Boolean, ): Boolean { val type = intent.resolveType(context) ?: return false + val uris = getIncomingUris(intent, type) return when { - type == MimeTypes.PlainText -> handlePlainText(intent, onPlainText) + uris.isEmpty() && type == MimeTypes.PlainText -> handlePlainText(intent, onPlainText) type.isMimeTypeImage() || type.isMimeTypeVideo() || type.isMimeTypeAudio() || @@ -67,7 +68,6 @@ class DefaultShareIntentHandler( type.isMimeTypeFile() || type.isMimeTypeText() || type.isMimeTypeAny() -> { - val uris = getIncomingUris(intent, type) val result = onUris(uris) revokeUriPermissions(uris.map { it.uri }) result From 7c6aa0655b4b933d31892692aad0a1898d30348b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 20 Nov 2025 16:22:56 +0100 Subject: [PATCH 003/113] item can be reordered, so hasPendingChanges should compare set and not list. --- .../rolesandpermissions/impl/roles/ChangeRolesPresenter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt index 86012462ce..d92ecaf0a1 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt @@ -104,7 +104,7 @@ class ChangeRolesPresenter( } } - val hasPendingChanges = usersWithRole.value != selectedUsers.value + val hasPendingChanges = usersWithRole.value.toSet() != selectedUsers.value.toSet() val roomInfo by room.roomInfoFlow.collectAsState() fun canChangeMemberRole(userId: UserId): Boolean { From c39c4260ebe64c1cbf2485edd93fef5c495af4a4 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 20 Nov 2025 16:23:41 +0100 Subject: [PATCH 004/113] Comparing mutable state was wrong --- .../rolesandpermissions/impl/roles/ChangeRolesPresenter.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt index d92ecaf0a1..6030279b98 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt @@ -134,11 +134,10 @@ class ChangeRolesPresenter( is ChangeRolesEvent.Save -> { val currentUserIsAdmin = roomInfo.roleOf(room.sessionId) == RoomMember.Role.Admin val isModifyingAdmins = role == RoomMember.Role.Admin - val hasChanges = selectedUsers != usersWithRole val isConfirming = saveState.value.isConfirming() val modifyingOwners = role is RoomMember.Role.Owner - val needsConfirmation = (modifyingOwners || currentUserIsAdmin && isModifyingAdmins) && hasChanges && !isConfirming + val needsConfirmation = (modifyingOwners || currentUserIsAdmin && isModifyingAdmins) && hasPendingChanges && !isConfirming when { needsConfirmation -> { From f8cd83db24453facb5ced9b5df2a2470a1350719 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 20 Nov 2025 16:56:01 +0100 Subject: [PATCH 005/113] Improve code around confirmation. --- .../impl/roles/ChangeRolesPresenter.kt | 17 +++++--- .../impl/roles/ChangeRolesView.kt | 40 ++++++++----------- .../impl/roles/ConfirmingModifyingAdmins.kt | 12 ++++++ .../impl/roles/ConfirmingModifyingOwners.kt | 12 ++++++ .../impl/roles/ChangeRolesPresenterTest.kt | 4 +- 5 files changed, 54 insertions(+), 31 deletions(-) create mode 100644 features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ConfirmingModifyingAdmins.kt create mode 100644 features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ConfirmingModifyingOwners.kt diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt index 6030279b98..781a909f4f 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt @@ -136,13 +136,18 @@ class ChangeRolesPresenter( val isModifyingAdmins = role == RoomMember.Role.Admin val isConfirming = saveState.value.isConfirming() val modifyingOwners = role is RoomMember.Role.Owner - - val needsConfirmation = (modifyingOwners || currentUserIsAdmin && isModifyingAdmins) && hasPendingChanges && !isConfirming - + val confirmationValue = if (hasPendingChanges && !isConfirming) { + when { + modifyingOwners -> ConfirmingModifyingOwners + currentUserIsAdmin && isModifyingAdmins -> ConfirmingModifyingAdmins + else -> null + } + } else { + null + } when { - needsConfirmation -> { - // Confirm modifying users - saveState.value = AsyncAction.ConfirmingNoParams + confirmationValue != null -> { + saveState.value = confirmationValue } !saveState.value.isLoading() -> { roomCoroutineScope.save(usersWithRole.value, selectedUsers, saveState) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt index 3a981b66b6..76cb334037 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt @@ -178,29 +178,23 @@ fun ChangeRolesView( onDismiss = { state.eventSink(ChangeRolesEvent.CloseDialog) } ) } - else -> { - when (state.role) { - is RoomMember.Role.Owner -> { - ConfirmationDialog( - title = stringResource(R.string.screen_room_change_role_confirm_change_owners_title), - content = stringResource(R.string.screen_room_change_role_confirm_change_owners_description), - submitText = stringResource(CommonStrings.action_continue), - onSubmitClick = { state.eventSink(ChangeRolesEvent.Save) }, - onDismiss = { state.eventSink(ChangeRolesEvent.CloseDialog) }, - destructiveSubmit = true, - ) - } - is RoomMember.Role.Admin -> { - ConfirmationDialog( - title = stringResource(R.string.screen_room_change_role_confirm_add_admin_title), - content = stringResource(R.string.screen_room_change_role_confirm_add_admin_description), - onSubmitClick = { state.eventSink(ChangeRolesEvent.Save) }, - onDismiss = { state.eventSink(ChangeRolesEvent.CloseDialog) } - ) - } - // No confirmation needed for Moderator or User roles - else -> Unit - } + is ConfirmingModifyingOwners -> { + ConfirmationDialog( + title = stringResource(R.string.screen_room_change_role_confirm_change_owners_title), + content = stringResource(R.string.screen_room_change_role_confirm_change_owners_description), + submitText = stringResource(CommonStrings.action_continue), + onSubmitClick = { state.eventSink(ChangeRolesEvent.Save) }, + onDismiss = { state.eventSink(ChangeRolesEvent.CloseDialog) }, + destructiveSubmit = true, + ) + } + is ConfirmingModifyingAdmins -> { + ConfirmationDialog( + title = stringResource(R.string.screen_room_change_role_confirm_add_admin_title), + content = stringResource(R.string.screen_room_change_role_confirm_add_admin_description), + onSubmitClick = { state.eventSink(ChangeRolesEvent.Save) }, + onDismiss = { state.eventSink(ChangeRolesEvent.CloseDialog) } + ) } } }, diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ConfirmingModifyingAdmins.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ConfirmingModifyingAdmins.kt new file mode 100644 index 0000000000..10d46abbc3 --- /dev/null +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ConfirmingModifyingAdmins.kt @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.rolesandpermissions.impl.roles + +import io.element.android.libraries.architecture.AsyncAction + +data object ConfirmingModifyingAdmins : AsyncAction.Confirming diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ConfirmingModifyingOwners.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ConfirmingModifyingOwners.kt new file mode 100644 index 0000000000..9799f68408 --- /dev/null +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ConfirmingModifyingOwners.kt @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.rolesandpermissions.impl.roles + +import io.element.android.libraries.architecture.AsyncAction + +data object ConfirmingModifyingOwners : AsyncAction.Confirming diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt index c5e28a5078..9b7a8971c3 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt @@ -358,7 +358,7 @@ class ChangeRolesPresenterTest { initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2))) awaitItem().eventSink(ChangeRolesEvent.Save) val confirmingState = awaitItem() - assertThat(confirmingState.savingState).isEqualTo(AsyncAction.ConfirmingNoParams) + assertThat(confirmingState.savingState).isEqualTo(ConfirmingModifyingAdmins) confirmingState.eventSink(ChangeRolesEvent.Save) assertThat(awaitItem().savingState).isInstanceOf(AsyncAction.Loading::class.java) assertThat(awaitItem().savingState).isEqualTo(AsyncAction.Success(true)) @@ -383,7 +383,7 @@ class ChangeRolesPresenterTest { awaitItem().eventSink(ChangeRolesEvent.Save) val confirmingState = awaitItem() - assertThat(confirmingState.savingState).isEqualTo(AsyncAction.ConfirmingNoParams) + assertThat(confirmingState.savingState).isEqualTo(ConfirmingModifyingAdmins) confirmingState.eventSink(ChangeRolesEvent.CloseDialog) assertThat(awaitItem().savingState).isEqualTo(AsyncAction.Uninitialized) From fbddfbdb0e167fb670679fe50688dc7e56b3b121 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 20 Nov 2025 17:23:21 +0100 Subject: [PATCH 006/113] Render room version in room detail screen if developer mode is enabled. --- .../roomdetails/impl/RoomDetailsPresenter.kt | 1 + .../roomdetails/impl/RoomDetailsState.kt | 1 + .../impl/RoomDetailsStateProvider.kt | 1 + .../roomdetails/impl/RoomDetailsView.kt | 19 ++++++++++++++++++- 4 files changed, 21 insertions(+), 1 deletion(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt index ec805731ec..232f4d626c 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt @@ -205,6 +205,7 @@ class RoomDetailsPresenter( canReportRoom = canReportRoom, isTombstoned = roomInfo.successorRoom != null, showDebugInfo = isDeveloperModeEnabled, + roomVersion = roomInfo.roomVersion, eventSink = ::handleEvent, ) } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt index 6e8d563d4a..2332776e96 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsState.kt @@ -49,6 +49,7 @@ data class RoomDetailsState( val canReportRoom: Boolean, val isTombstoned: Boolean, val showDebugInfo: Boolean, + val roomVersion: String?, val eventSink: (RoomDetailsEvent) -> Unit ) { val roomBadges = buildList { diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt index cbb54071a1..783fcfaf10 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsStateProvider.kt @@ -146,6 +146,7 @@ fun aRoomDetailsState( canReportRoom = canReportRoom, isTombstoned = isTombstoned, showDebugInfo = showDebugInfo, + roomVersion = "12", eventSink = eventSink, ) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt index fe4a002af8..de0a2cba1b 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsView.kt @@ -264,6 +264,7 @@ fun RoomDetailsView( if (state.showDebugInfo) { DebugInfoSection( roomId = state.roomId, + roomVersion = state.roomVersion, ) } } @@ -714,7 +715,10 @@ private fun OtherActionsSection( } @Composable -private fun DebugInfoSection(roomId: RoomId) { +private fun DebugInfoSection( + roomId: RoomId, + roomVersion: String?, +) { val context = LocalContext.current PreferenceCategory(showTopDivider = true) { ListItem( @@ -737,6 +741,19 @@ private fun DebugInfoSection(roomId: RoomId) { ) }, ) + ListItem( + headlineContent = { + Text("Room version") + }, + supportingContent = { + Text( + text = roomVersion ?: "Unknown", + style = ElementTheme.typography.fontBodySmRegular, + color = ElementTheme.colors.textSecondary, + ) + }, + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Info())), + ) } } From 729e5e9218759a58d5efb4ce3ccf0c69077e7e49 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 20 Nov 2025 17:29:01 +0100 Subject: [PATCH 007/113] Fix roleOf extension. Creator are Owner Role only if privilegedCreatorRole is true. --- .../matrix/test/room/RoomInfoFixture.kt | 2 +- .../matrix/ui/model/RoomInfoExtension.kt | 4 +- .../matrix/ui/model/RoomInfoExtensionTest.kt | 79 +++++++++++++++++++ 3 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/model/RoomInfoExtensionTest.kt diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomInfoFixture.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomInfoFixture.kt index abb24fc153..71ed8b83be 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomInfoFixture.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomInfoFixture.kt @@ -53,7 +53,7 @@ fun aRoomInfo( notificationCount: Long = 0, userDefinedNotificationMode: RoomNotificationMode? = null, hasRoomCall: Boolean = false, - roomPowerLevels: RoomPowerLevels = RoomPowerLevels( + roomPowerLevels: RoomPowerLevels? = RoomPowerLevels( values = defaultRoomPowerLevelValues(), users = persistentMapOf(), ), diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomInfoExtension.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomInfoExtension.kt index 52e7d43085..f9a86c9bd7 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomInfoExtension.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/model/RoomInfoExtension.kt @@ -23,12 +23,12 @@ fun RoomInfo.getAvatarData(size: AvatarSize) = AvatarData( /** * Returns the role of the user in the room. - * If the user is a creator, returns [RoomMember.Role.Owner]. + * If the user is a creator and [RoomInfo.privilegedCreatorRole] is true, returns [RoomMember.Role.Owner]. * Otherwise, checks the power levels and returns the corresponding role. * If no specific power level is set for the user, defaults to [RoomMember.Role.User]. */ fun RoomInfo.roleOf(userId: UserId): RoomMember.Role { - return if (creators.contains(userId)) { + return if (privilegedCreatorRole && creators.contains(userId)) { RoomMember.Role.Owner(isCreator = true) } else { roomPowerLevels?.roleOf(userId) ?: RoomMember.Role.User diff --git a/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/model/RoomInfoExtensionTest.kt b/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/model/RoomInfoExtensionTest.kt new file mode 100644 index 0000000000..c6dcc27bba --- /dev/null +++ b/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/model/RoomInfoExtensionTest.kt @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.matrix.ui.model + +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.api.room.RoomMember +import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels +import io.element.android.libraries.matrix.test.A_USER_ID +import io.element.android.libraries.matrix.test.A_USER_ID_2 +import io.element.android.libraries.matrix.test.A_USER_ID_3 +import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.libraries.matrix.test.room.defaultRoomPowerLevelValues +import kotlinx.collections.immutable.toImmutableMap +import org.junit.Test + +class RoomInfoExtensionTest { + @Test + fun `roleOf returns Owner for creator with privilegedCreatorRole true`() { + val roomInfo = aRoomInfo( + privilegedCreatorRole = true, + roomCreators = listOf(A_USER_ID), + ) + assertThat(roomInfo.roleOf(A_USER_ID)).isEqualTo(RoomMember.Role.Owner(isCreator = true)) + } + + @Test + fun `roleOf returns User for not creator with privilegedCreatorRole true`() { + val roomInfo = aRoomInfo( + privilegedCreatorRole = true, + roomCreators = listOf(A_USER_ID), + ) + assertThat(roomInfo.roleOf(A_USER_ID_2)).isEqualTo(RoomMember.Role.User) + } + + @Test + fun `roleOf returns User for creator with privilegedCreatorRole false`() { + val roomInfo = aRoomInfo( + privilegedCreatorRole = false, + roomCreators = listOf(A_USER_ID), + ) + assertThat(roomInfo.roleOf(A_USER_ID)).isEqualTo(RoomMember.Role.User) + } + + @Test + fun `roleOf returns role from the power level`() { + val roomInfo = aRoomInfo( + privilegedCreatorRole = false, + roomPowerLevels = RoomPowerLevels( + values = defaultRoomPowerLevelValues(), + users = mapOf( + A_USER_ID to 100L, // Admin + A_USER_ID_2 to 50L, // Moderator + A_USER_ID_3 to 0L, // User + ).toImmutableMap(), + ), + roomCreators = listOf(A_USER_ID), + ) + assertThat(roomInfo.roleOf(A_USER_ID)).isEqualTo(RoomMember.Role.Admin) + assertThat(roomInfo.roleOf(A_USER_ID_2)).isEqualTo(RoomMember.Role.Moderator) + assertThat(roomInfo.roleOf(A_USER_ID_3)).isEqualTo(RoomMember.Role.User) + } + + @Test + fun `roleOf returns User when the power level is null`() { + val roomInfo = aRoomInfo( + privilegedCreatorRole = false, + roomPowerLevels = null, + roomCreators = listOf(A_USER_ID), + ) + assertThat(roomInfo.roleOf(A_USER_ID)).isEqualTo(RoomMember.Role.User) + assertThat(roomInfo.roleOf(A_USER_ID_2)).isEqualTo(RoomMember.Role.User) + assertThat(roomInfo.roleOf(A_USER_ID_3)).isEqualTo(RoomMember.Role.User) + } +} From fafb243eb28f18039057c5ba4db9fbc9a1598760 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 20 Nov 2025 18:06:55 +0100 Subject: [PATCH 008/113] Fix and add missing preview. --- .../impl/roles/ChangeRolesStateProvider.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesStateProvider.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesStateProvider.kt index df74b71ae1..2594681850 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesStateProvider.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesStateProvider.kt @@ -46,7 +46,7 @@ class ChangeRolesStateProvider : PreviewParameterProvider { selectedUsers = aMatrixUserList().take(1).toImmutableList(), ), aChangeRolesStateWithSelectedUsers().copy(savingState = AsyncAction.ConfirmingCancellation), - aChangeRolesStateWithSelectedUsers().copy(savingState = AsyncAction.ConfirmingNoParams), + aChangeRolesStateWithSelectedUsers().copy(savingState = ConfirmingModifyingAdmins), aChangeRolesStateWithSelectedUsers().copy(savingState = AsyncAction.Loading), aChangeRolesStateWithSelectedUsers().copy(savingState = AsyncAction.Success(true)), aChangeRolesStateWithSelectedUsers().copy(savingState = AsyncAction.Failure(Exception("boom"))), @@ -58,6 +58,8 @@ class ChangeRolesStateProvider : PreviewParameterProvider { ) ), aChangeRolesStateWithOwners(role = RoomMember.Role.Owner(isCreator = false)), + aChangeRolesStateWithOwners(role = RoomMember.Role.Owner(isCreator = false)) + .copy(savingState = ConfirmingModifyingOwners), ) } From c814bf1a73eb8db57b7e6029961834d339d40b6c Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 21 Nov 2025 08:35:49 +0000 Subject: [PATCH 009/113] Update screenshots --- ...olesandpermissions.impl.roles_ChangeRolesView_Day_13_en.png | 3 +++ ...esandpermissions.impl.roles_ChangeRolesView_Night_13_en.png | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en.png new file mode 100644 index 0000000000..5ae55a94d8 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:fbee2417fcd701fce6d3f4d20e677681de6d529e5a17f0bfffc1c1592d73398a +size 58939 diff --git a/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en.png b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en.png new file mode 100644 index 0000000000..8fb608a939 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:41698290446bc0f2e58fac106cdef381c1b46f3655ff51fff574ff867cd70d10 +size 57006 From f03f64ad3b0f6323897d58a0798e129a8aa7563c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 09:33:41 +0100 Subject: [PATCH 010/113] Avoid computing the boolean on each recomposition. --- .../rolesandpermissions/impl/roles/ChangeRolesPresenter.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt index 781a909f4f..fdb17d6e04 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt @@ -12,6 +12,7 @@ import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect import androidx.compose.runtime.MutableState import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf import androidx.compose.runtime.produceState @@ -104,7 +105,11 @@ class ChangeRolesPresenter( } } - val hasPendingChanges = usersWithRole.value.toSet() != selectedUsers.value.toSet() + val hasPendingChanges by remember { + derivedStateOf { + usersWithRole.value.toSet() != selectedUsers.value.toSet() + } + } val roomInfo by room.roomInfoFlow.collectAsState() fun canChangeMemberRole(userId: UserId): Boolean { From 37e395d480e36a5742a1fcfc56f9394faf12eff3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 09:40:32 +0100 Subject: [PATCH 011/113] Fix and add test --- .../impl/roles/ChangeRolesPresenterTest.kt | 54 ++++++++++++++++++- 1 file changed, 52 insertions(+), 2 deletions(-) diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt index 9b7a8971c3..5c2491e0d3 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt @@ -74,7 +74,7 @@ class ChangeRolesPresenterTest { } @Test - fun `present - canChangeRole of users with lower power level unless they are owners`() = runTest { + fun `present - canChangeRole of users with lower power level unless they are owners - privilegedCreatorRole is true`() = runTest { val creatorUserId = UserId("@creator:matrix.org") val superAdminUserId = UserId("@super_admin:matrix.org") @@ -82,6 +82,7 @@ class ChangeRolesPresenterTest { // User is a creator, so they can change roles of other members. So is `creatorUserId`. givenRoomInfo( aRoomInfo( + privilegedCreatorRole = true, roomCreators = listOf(sessionId, creatorUserId), roomPowerLevels = RoomPowerLevels( defaultRoomPowerLevelValues(), @@ -99,7 +100,7 @@ class ChangeRolesPresenterTest { val roomMemberList = aRoomMemberList() + listOf( // Owner - superadmin - aRoomMember(userId = superAdminUserId, role = RoomMember.Role.Owner(isCreator = true)), + aRoomMember(userId = superAdminUserId, role = RoomMember.Role.Owner(isCreator = false)), // Owner - creator aRoomMember(userId = creatorUserId, role = RoomMember.Role.Owner(isCreator = true)) ) @@ -118,6 +119,55 @@ class ChangeRolesPresenterTest { } } + @Test + fun `present - canChangeRole of users with lower power level unless they are owners - privilegedCreatorRole is false`() = runTest { + val creatorUserId = UserId("@creator:matrix.org") + val superAdminUserId = UserId("@super_admin:matrix.org") + + val room = FakeJoinedRoom().apply { + // User is a creator, so they can change roles of other members. So is `creatorUserId`. + givenRoomInfo( + aRoomInfo( + privilegedCreatorRole = false, + roomCreators = listOf(sessionId, creatorUserId), + roomPowerLevels = RoomPowerLevels( + defaultRoomPowerLevelValues(), + users = persistentMapOf( + // Creator is an admin + sessionId to RoomMember.Role.Admin.powerLevel, + creatorUserId to RoomMember.Role.Admin.powerLevel, + // bob is Admin + A_USER_ID_2 to RoomMember.Role.Admin.powerLevel, + // carol is Moderator + A_USER_ID_3 to RoomMember.Role.Moderator.powerLevel, + // super_admin is Owner - Superadmin + superAdminUserId to RoomMember.Role.Owner(isCreator = false).powerLevel, + ) + ) + ) + ) + + val roomMemberList = aRoomMemberList() + listOf( + // Owner - superadmin + aRoomMember(userId = superAdminUserId, role = RoomMember.Role.Owner(isCreator = false)), + // Owner - creator + aRoomMember(userId = creatorUserId, role = RoomMember.Role.Owner(isCreator = true)) + ) + givenRoomMembersState(RoomMembersState.Ready(roomMemberList.toImmutableList())) + } + val presenter = createChangeRolesPresenter(room = room) + moleculeFlow(RecompositionMode.Immediate) { + presenter.present() + }.test { + skipItems(1) + awaitItem().run { + assertThat(canChangeMemberRole(A_USER_ID_2)).isFalse() // Creator cannot update Admin in this case + assertThat(canChangeMemberRole(A_USER_ID_3)).isTrue() // Moderator + assertThat(canChangeMemberRole(creatorUserId)).isFalse() // Owner + } + } + } + @Test fun `present - when modifying admins, creators are displayed too`() = runTest { val room = FakeJoinedRoom().apply { From 2ffbd8036351e5763b639f268747619469ad12d3 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 09:42:49 +0100 Subject: [PATCH 012/113] Use test extension --- .../impl/roles/ChangeRolesPresenterTest.kt | 80 +++++-------------- 1 file changed, 20 insertions(+), 60 deletions(-) diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt index 5c2491e0d3..472426ff85 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt @@ -8,9 +8,6 @@ package io.element.android.features.rolesandpermissions.impl.roles -import app.cash.molecule.RecompositionMode -import app.cash.molecule.moleculeFlow -import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import im.vector.app.features.analytics.plan.RoomModeration import io.element.android.libraries.architecture.AsyncAction @@ -31,6 +28,7 @@ import io.element.android.libraries.matrix.test.room.aRoomMember import io.element.android.libraries.matrix.test.room.defaultRoomPowerLevelValues import io.element.android.libraries.previewutils.room.aRoomMemberList import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.tests.testutils.test import io.element.android.tests.testutils.testCoroutineDispatchers import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.toImmutableList @@ -43,9 +41,7 @@ class ChangeRolesPresenterTest { @Test fun `present - initial state`() = runTest { val presenter = createChangeRolesPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { with(awaitItem()) { assertThat(role).isEqualTo(RoomMember.Role.Admin) assertThat(query).isNull() @@ -65,9 +61,7 @@ class ChangeRolesPresenterTest { givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) } val presenter = createChangeRolesPresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) assertThat(awaitItem().searchResults).isInstanceOf(SearchBarResultState.Results::class.java) } @@ -107,9 +101,7 @@ class ChangeRolesPresenterTest { givenRoomMembersState(RoomMembersState.Ready(roomMemberList.toImmutableList())) } val presenter = createChangeRolesPresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) awaitItem().run { assertThat(canChangeMemberRole(A_USER_ID_2)).isTrue() // Admin @@ -156,9 +148,7 @@ class ChangeRolesPresenterTest { givenRoomMembersState(RoomMembersState.Ready(roomMemberList.toImmutableList())) } val presenter = createChangeRolesPresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) awaitItem().run { assertThat(canChangeMemberRole(A_USER_ID_2)).isFalse() // Creator cannot update Admin in this case @@ -179,9 +169,7 @@ class ChangeRolesPresenterTest { givenRoomMembersState(RoomMembersState.Ready(memberList)) } val presenter = createChangeRolesPresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) awaitItem().searchResults.run { assertThat(this).isInstanceOf(SearchBarResultState.Results::class.java) @@ -199,9 +187,7 @@ class ChangeRolesPresenterTest { givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) } val presenter = createChangeRolesPresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(ChangeRolesEvent.ToggleSearchActive) @@ -218,9 +204,7 @@ class ChangeRolesPresenterTest { givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) } val presenter = createChangeRolesPresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() val initialResults = (awaitItem().searchResults as? SearchBarResultState.Results)?.results assertThat(initialResults?.members).hasSize(8) @@ -244,9 +228,7 @@ class ChangeRolesPresenterTest { givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) } val presenter = createChangeRolesPresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) val initialResults = (awaitItem().searchResults as? SearchBarResultState.Results)?.results assertThat(initialResults?.members).hasSize(8) @@ -271,9 +253,7 @@ class ChangeRolesPresenterTest { givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin))) } val presenter = createChangeRolesPresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) val initialState = awaitItem() assertThat(initialState.selectedUsers).hasSize(1) @@ -293,9 +273,7 @@ class ChangeRolesPresenterTest { givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin))) } val presenter = createChangeRolesPresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) val initialState = awaitItem() assertThat(initialState.hasPendingChanges).isFalse() @@ -322,9 +300,7 @@ class ChangeRolesPresenterTest { givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin))) } val presenter = createChangeRolesPresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) val initialState = awaitItem() assertThat(initialState.hasPendingChanges).isFalse() @@ -342,9 +318,7 @@ class ChangeRolesPresenterTest { givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin))) } val presenter = createChangeRolesPresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) val initialState = awaitItem() assertThat(initialState.hasPendingChanges).isFalse() @@ -368,9 +342,7 @@ class ChangeRolesPresenterTest { givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin))) } val presenter = createChangeRolesPresenter(room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) val initialState = awaitItem() assertThat(initialState.hasPendingChanges).isFalse() @@ -399,9 +371,7 @@ class ChangeRolesPresenterTest { givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin))) } val presenter = createChangeRolesPresenter(role = RoomMember.Role.Admin, room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(2) val initialState = awaitItem() assertThat(initialState.selectedUsers).hasSize(1) @@ -422,9 +392,7 @@ class ChangeRolesPresenterTest { givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(RoomMember.Role.Admin))) } val presenter = createChangeRolesPresenter(role = RoomMember.Role.Admin, room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) val initialState = awaitItem() assertThat(initialState.selectedUsers).hasSize(1) @@ -455,9 +423,7 @@ class ChangeRolesPresenterTest { room = room, analyticsService = analyticsService ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(2) val initialState = awaitItem() assertThat(initialState.selectedUsers).hasSize(1) @@ -492,9 +458,7 @@ class ChangeRolesPresenterTest { room = room, analyticsService = analyticsService ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) val initialState = awaitItem() assertThat(initialState.selectedUsers).hasSize(1) @@ -527,9 +491,7 @@ class ChangeRolesPresenterTest { room = room, analyticsService = analyticsService ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(2) val initialState = awaitItem() assertThat(initialState.selectedUsers).hasSize(1) @@ -554,9 +516,7 @@ class ChangeRolesPresenterTest { givenRoomInfo(aRoomInfo(roomPowerLevels = roomPowerLevelsWithRole(role = RoomMember.Role.Moderator, userId = A_USER_ID))) } val presenter = createChangeRolesPresenter(role = RoomMember.Role.Moderator, room = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(2) val initialState = awaitItem() assertThat(initialState.selectedUsers).hasSize(1) From f801a0b47f96a4846cef8c85e6a946d0fcc59c03 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 11:53:28 +0100 Subject: [PATCH 013/113] Show not save dialog when exiting user profile edition with unsaved changes --- .../user/editprofile/EditUserProfileEvents.kt | 3 +- .../user/editprofile/EditUserProfileNode.kt | 17 +++++-- .../editprofile/EditUserProfilePresenter.kt | 44 +++++++++++++++---- .../user/editprofile/EditUserProfileView.kt | 28 ++++++++++-- .../EditUserProfilePresenterTest.kt | 6 ++- .../architecture/navigation/BaseNavigator.kt | 12 +++++ 6 files changed, 91 insertions(+), 19 deletions(-) create mode 100644 libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseNavigator.kt diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileEvents.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileEvents.kt index ba62c6103f..f7f2ffceb4 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileEvents.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileEvents.kt @@ -13,6 +13,7 @@ import io.element.android.libraries.matrix.ui.media.AvatarAction sealed interface EditUserProfileEvents { data class HandleAvatarAction(val action: AvatarAction) : EditUserProfileEvents data class UpdateDisplayName(val name: String) : EditUserProfileEvents + data object Exit : EditUserProfileEvents data object Save : EditUserProfileEvents - data object CancelSaveChanges : EditUserProfileEvents + data object CloseDialog : EditUserProfileEvents } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt index d37ad888ce..3d939cfbd4 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt @@ -18,6 +18,7 @@ import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.inputs +import io.element.android.libraries.architecture.navigation.BaseNavigator import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.user.MatrixUser @@ -27,22 +28,30 @@ class EditUserProfileNode( @Assisted buildContext: BuildContext, @Assisted plugins: List, presenterFactory: EditUserProfilePresenter.Factory, -) : Node(buildContext, plugins = plugins) { +) : Node(buildContext, plugins = plugins), + BaseNavigator { data class Inputs( val matrixUser: MatrixUser ) : NodeInputs val matrixUser = inputs().matrixUser - val presenter = presenterFactory.create(matrixUser) + val presenter = presenterFactory.create( + matrixUser = matrixUser, + navigator = this, + ) @Composable override fun View(modifier: Modifier) { val state = presenter.present() EditUserProfileView( state = state, - onBackClick = ::navigateUp, - onEditProfileSuccess = ::navigateUp, + onEditProfileSuccess = ::close, modifier = modifier ) } + + override fun close() { + // TODO Invoke callback + navigateUp() + } } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt index 0f46abb918..46298c96a2 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt @@ -26,6 +26,7 @@ import dev.zacsweers.metro.AssistedInject import io.element.android.libraries.androidutils.file.TemporaryUriDeleter import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.architecture.navigation.BaseNavigator import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.core.mimetype.MimeTypes @@ -45,6 +46,7 @@ import timber.log.Timber @AssistedInject class EditUserProfilePresenter( @Assisted private val matrixUser: MatrixUser, + @Assisted private val navigator: BaseNavigator, private val matrixClient: MatrixClient, private val mediaPickerProvider: PickerProvider, private val mediaPreProcessor: MediaPreProcessor, @@ -57,7 +59,10 @@ class EditUserProfilePresenter( @AssistedFactory interface Factory { - fun create(matrixUser: MatrixUser): EditUserProfilePresenter + fun create( + matrixUser: MatrixUser, + navigator: BaseNavigator, + ): EditUserProfilePresenter } @Composable @@ -101,6 +106,13 @@ class EditUserProfilePresenter( val saveAction: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } val localCoroutineScope = rememberCoroutineScope() + + val canSave = remember(userDisplayName, userAvatarUri) { + val hasProfileChanged = hasDisplayNameChanged(userDisplayName, matrixUser) || + hasAvatarUrlChanged(userAvatarUri, matrixUser) + !userDisplayName.isNullOrBlank() && hasProfileChanged + } + fun handleEvent(event: EditUserProfileEvents) { when (event) { is EditUserProfileEvents.Save -> localCoroutineScope.saveChanges( @@ -124,18 +136,32 @@ class EditUserProfilePresenter( } } } - is EditUserProfileEvents.UpdateDisplayName -> userDisplayName = event.name - EditUserProfileEvents.CancelSaveChanges -> saveAction.value = AsyncAction.Uninitialized + EditUserProfileEvents.Exit -> { + when (saveAction.value) { + is AsyncAction.Confirming -> { + // Close the dialog right now + saveAction.value = AsyncAction.Uninitialized + navigator.close() + } + AsyncAction.Loading -> Unit + is AsyncAction.Failure, + is AsyncAction.Success -> { + // Should not happen + } + AsyncAction.Uninitialized -> { + if (canSave) { + saveAction.value = AsyncAction.ConfirmingCancellation + } else { + navigator.close() + } + } + } + } + EditUserProfileEvents.CloseDialog -> saveAction.value = AsyncAction.Uninitialized } } - val canSave = remember(userDisplayName, userAvatarUri) { - val hasProfileChanged = hasDisplayNameChanged(userDisplayName, matrixUser) || - hasAvatarUrlChanged(userAvatarUri, matrixUser) - !userDisplayName.isNullOrBlank() && hasProfileChanged - } - return EditUserProfileState( userId = matrixUser.userId, displayName = userDisplayName.orEmpty(), diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt index 91394d19a6..d6f0fcbd2c 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileView.kt @@ -8,6 +8,7 @@ package io.element.android.features.preferences.impl.user.editprofile +import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Spacer import androidx.compose.foundation.layout.fillMaxWidth @@ -30,11 +31,13 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.features.preferences.impl.R +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.avatar.AvatarType import io.element.android.libraries.designsystem.components.button.BackButton +import io.element.android.libraries.designsystem.components.dialogs.SaveChangesDialog import io.element.android.libraries.designsystem.modifiers.clearFocusOnTap import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight @@ -52,7 +55,6 @@ import io.element.android.libraries.ui.strings.CommonStrings @Composable fun EditUserProfileView( state: EditUserProfileState, - onBackClick: () -> Unit, onEditProfileSuccess: () -> Unit, modifier: Modifier = Modifier, ) { @@ -64,12 +66,21 @@ fun EditUserProfileView( isAvatarActionsSheetVisible.value = true } + fun onBackClick() { + focusManager.clearFocus() + state.eventSink(EditUserProfileEvents.Exit) + } + + BackHandler( + enabled = true, + ::onBackClick, + ) Scaffold( modifier = modifier.clearFocusOnTap(focusManager), topBar = { TopAppBar( titleStr = stringResource(R.string.screen_edit_profile_title), - navigationIcon = { BackButton(onClick = onBackClick) }, + navigationIcon = { BackButton(::onBackClick) }, actions = { TextButton( text = stringResource(CommonStrings.action_save), @@ -132,10 +143,20 @@ fun EditUserProfileView( progressText = stringResource(R.string.screen_edit_profile_updating_details), ) }, + confirmationDialog = { confirming -> + when (confirming) { + is AsyncAction.ConfirmingCancellation -> { + SaveChangesDialog( + onSubmitClick = { state.eventSink(EditUserProfileEvents.Exit) }, + onDismiss = { state.eventSink(EditUserProfileEvents.CloseDialog) } + ) + } + } + }, onSuccess = { onEditProfileSuccess() }, errorTitle = { stringResource(R.string.screen_edit_profile_error_title) }, errorMessage = { stringResource(R.string.screen_edit_profile_error) }, - onErrorDismiss = { state.eventSink(EditUserProfileEvents.CancelSaveChanges) }, + onErrorDismiss = { state.eventSink(EditUserProfileEvents.CloseDialog) }, ) } PermissionsView( @@ -148,7 +169,6 @@ fun EditUserProfileView( internal fun EditUserProfileViewPreview(@PreviewParameter(EditUserProfileStateProvider::class) state: EditUserProfileState) = ElementPreview { EditUserProfileView( - onBackClick = {}, onEditProfileSuccess = {}, state = state, ) diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt index 0840dea2db..7c24cd0492 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt @@ -15,6 +15,7 @@ import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.libraries.androidutils.file.TemporaryUriDeleter import io.element.android.libraries.architecture.AsyncAction +import io.element.android.libraries.architecture.navigation.BaseNavigator import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.test.AN_AVATAR_URL @@ -33,6 +34,7 @@ import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.consumeItemsUntilPredicate import io.element.android.tests.testutils.consumeItemsUntilTimeout import io.element.android.tests.testutils.fake.FakeTemporaryUriDeleter +import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value import io.mockk.every @@ -79,6 +81,7 @@ class EditUserProfilePresenterTest { private fun createEditUserProfilePresenter( matrixClient: MatrixClient = FakeMatrixClient(), + navigator: BaseNavigator = BaseNavigator { lambdaError() }, matrixUser: MatrixUser = aMatrixUser(), permissionsPresenter: PermissionsPresenter = FakePermissionsPresenter(), temporaryUriDeleter: TemporaryUriDeleter = FakeTemporaryUriDeleter(), @@ -86,6 +89,7 @@ class EditUserProfilePresenterTest { ): EditUserProfilePresenter { return EditUserProfilePresenter( matrixClient = matrixClient, + navigator = navigator, matrixUser = matrixUser, mediaPickerProvider = fakePickerProvider, mediaPreProcessor = fakeMediaPreProcessor, @@ -456,7 +460,7 @@ class EditUserProfilePresenterTest { initialState.eventSink(EditUserProfileEvents.Save) skipItems(2) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Failure::class.java) - initialState.eventSink(EditUserProfileEvents.CancelSaveChanges) + initialState.eventSink(EditUserProfileEvents.CloseDialog) assertThat(awaitItem().saveAction).isInstanceOf(AsyncAction.Uninitialized::class.java) } } diff --git a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseNavigator.kt b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseNavigator.kt new file mode 100644 index 0000000000..5cc61166fe --- /dev/null +++ b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseNavigator.kt @@ -0,0 +1,12 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.architecture.navigation + +fun interface BaseNavigator { + fun close() +} From c67f257af0fe9fa5cc04603f6485ee3b0ae31686 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 11:56:26 +0100 Subject: [PATCH 014/113] Use test extension --- .../EditUserProfilePresenterTest.kt | 56 +++++-------------- 1 file changed, 14 insertions(+), 42 deletions(-) diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt index 7c24cd0492..bf5d138b3f 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt @@ -9,9 +9,6 @@ package io.element.android.features.preferences.impl.user.editprofile import android.net.Uri -import app.cash.molecule.RecompositionMode -import app.cash.molecule.moleculeFlow -import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.libraries.androidutils.file.TemporaryUriDeleter import io.element.android.libraries.architecture.AsyncAction @@ -37,6 +34,7 @@ import io.element.android.tests.testutils.fake.FakeTemporaryUriDeleter import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value +import io.element.android.tests.testutils.test import io.mockk.every import io.mockk.mockk import io.mockk.mockkStatic @@ -103,9 +101,7 @@ class EditUserProfilePresenterTest { fun `present - initial state is created from user info`() = runTest { val user = aMatrixUser(avatarUrl = AN_AVATAR_URL) val presenter = createEditUserProfilePresenter(matrixUser = user) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() assertThat(initialState.userId).isEqualTo(user.userId) assertThat(initialState.displayName).isEqualTo(user.displayName) @@ -129,9 +125,7 @@ class EditUserProfilePresenterTest { deleteLambda = { assertThat(it).isEqualTo(userAvatarUri) } ), ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() assertThat(initialState.displayName).isEqualTo("Name") assertThat(initialState.userAvatarUrl).isEqualTo(AN_AVATAR_URL) @@ -163,9 +157,7 @@ class EditUserProfilePresenterTest { deleteLambda = { assertThat(it).isEqualTo(userAvatarUri) } ), ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() assertThat(initialState.userAvatarUrl).isEqualTo(AN_AVATAR_URL) initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) @@ -188,9 +180,7 @@ class EditUserProfilePresenterTest { deleteLambda = deleteCallback, ), ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() assertThat(initialState.userAvatarUrl).isEqualTo(AN_AVATAR_URL) assertThat(initialState.cameraPermissionState.permissionGranted).isFalse() @@ -225,9 +215,7 @@ class EditUserProfilePresenterTest { deleteLambda = deleteCallback ), ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() assertThat(initialState.saveButtonEnabled).isFalse() // Once a change is made, the save button is enabled @@ -268,9 +256,7 @@ class EditUserProfilePresenterTest { deleteLambda = deleteCallback ), ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() assertThat(initialState.saveButtonEnabled).isFalse() // Once a change is made, the save button is enabled @@ -311,9 +297,7 @@ class EditUserProfilePresenterTest { deleteLambda = { assertThat(it).isEqualTo(userAvatarUri) } ), ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("New name")) initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.Remove)) @@ -334,9 +318,7 @@ class EditUserProfilePresenterTest { matrixClient = matrixClient, matrixUser = user ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(EditUserProfileEvents.UpdateDisplayName(" Name ")) initialState.eventSink(EditUserProfileEvents.Save) @@ -355,9 +337,7 @@ class EditUserProfilePresenterTest { matrixClient = matrixClient, matrixUser = user ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("")) initialState.eventSink(EditUserProfileEvents.Save) @@ -380,9 +360,7 @@ class EditUserProfilePresenterTest { deleteLambda = { assertThat(it).isEqualTo(userAvatarUri) } ), ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) initialState.eventSink(EditUserProfileEvents.Save) @@ -404,9 +382,7 @@ class EditUserProfilePresenterTest { ) fakePickerProvider.givenResult(anotherAvatarUri) fakeMediaPreProcessor.givenResult(Result.failure(RuntimeException("Oh no"))) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(EditUserProfileEvents.HandleAvatarAction(AvatarAction.ChoosePhoto)) initialState.eventSink(EditUserProfileEvents.Save) @@ -452,9 +428,7 @@ class EditUserProfilePresenterTest { givenSetDisplayNameResult(Result.failure(RuntimeException("!"))) } val presenter = createEditUserProfilePresenter(matrixUser = user, matrixClient = matrixClient) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("foo")) initialState.eventSink(EditUserProfileEvents.Save) @@ -473,9 +447,7 @@ class EditUserProfilePresenterTest { deleteLambda = { assertThat(it).isEqualTo(userAvatarUri) } ), ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(event) initialState.eventSink(EditUserProfileEvents.Save) From c8b4c1f29e429768c725a590b3ff2bcbafa72a13 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 12:03:38 +0100 Subject: [PATCH 015/113] Add unit tests --- .../EditUserProfilePresenterTest.kt | 49 ++++++++++++++++++- 1 file changed, 48 insertions(+), 1 deletion(-) diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt index bf5d138b3f..a39b2013b6 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt @@ -116,6 +116,53 @@ class EditUserProfilePresenterTest { } } + @Test + fun `present - exit invokes the expected callback`() = runTest { + val user = aMatrixUser(avatarUrl = AN_AVATAR_URL) + val closeLambda = lambdaRecorder {} + val presenter = createEditUserProfilePresenter( + matrixUser = user, + navigator = BaseNavigator { closeLambda() }, + ) + presenter.test { + val initialState = awaitItem() + initialState.eventSink(EditUserProfileEvents.Exit) + closeLambda.assertions().isCalledOnce() + } + } + + @Test + fun `present - exit without unsaved changes`() = runTest { + val user = aMatrixUser(avatarUrl = AN_AVATAR_URL) + val closeLambda = lambdaRecorder {} + val presenter = createEditUserProfilePresenter( + matrixUser = user, + navigator = BaseNavigator { closeLambda() }, + ) + presenter.test { + val initialState = awaitItem() + initialState.eventSink(EditUserProfileEvents.UpdateDisplayName("New name")) + val withUpdatedName = awaitItem() + withUpdatedName.eventSink(EditUserProfileEvents.Exit) + val withConfirmation = awaitItem() + assertThat(withConfirmation.saveAction).isEqualTo(AsyncAction.ConfirmingCancellation) + // Cancel + withConfirmation.eventSink(EditUserProfileEvents.CloseDialog) + val afterCancel = awaitItem() + assertThat(afterCancel.saveAction).isEqualTo(AsyncAction.Uninitialized) + // Try again and confirm + afterCancel.eventSink(EditUserProfileEvents.Exit) + val withConfirmation2 = awaitItem() + assertThat(withConfirmation2.saveAction).isEqualTo(AsyncAction.ConfirmingCancellation) + closeLambda.assertions().isNeverCalled() + withConfirmation2.eventSink(EditUserProfileEvents.Exit) + // Dialog is closed + val finalState = awaitItem() + assertThat(finalState.saveAction).isEqualTo(AsyncAction.Uninitialized) + closeLambda.assertions().isCalledOnce() + } + } + @Test fun `present - updates state in response to changes`() = runTest { val user = aMatrixUser(id = A_USER_ID.value, displayName = "Name", avatarUrl = AN_AVATAR_URL) @@ -421,7 +468,7 @@ class EditUserProfilePresenterTest { } @Test - fun `present - CancelSaveChanges resets save action state`() = runTest { + fun `present - CloseDialog resets save action state`() = runTest { givenPickerReturnsFile() val user = aMatrixUser(id = A_USER_ID.value, displayName = "Name", avatarUrl = AN_AVATAR_URL) val matrixClient = FakeMatrixClient().apply { From 4dd148d3719241c02b2c2b84ff53d9a4964705a9 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 14:24:48 +0100 Subject: [PATCH 016/113] Add preview --- .../EditUserProfileStateProvider.kt | 27 ++++++++++++------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt index 7b373293c4..56b734a342 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileStateProvider.kt @@ -11,27 +11,36 @@ package io.element.android.features.preferences.impl.user.editprofile import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.ui.media.AvatarAction +import io.element.android.libraries.permissions.api.PermissionsState import io.element.android.libraries.permissions.api.aPermissionsState -import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList open class EditUserProfileStateProvider : PreviewParameterProvider { override val values: Sequence get() = sequenceOf( aEditUserProfileState(), aEditUserProfileState(userAvatarUrl = "example://uri"), - // Add other states here + aEditUserProfileState(saveAction = AsyncAction.ConfirmingCancellation), ) } fun aEditUserProfileState( + userId: UserId = UserId("@john.doe:matrix.org"), + displayName: String = "John Doe", userAvatarUrl: String? = null, + avatarActions: List = emptyList(), + saveButtonEnabled: Boolean = true, + saveAction: AsyncAction = AsyncAction.Uninitialized, + cameraPermissionState: PermissionsState = aPermissionsState(showDialog = false), + eventSink: (EditUserProfileEvents) -> Unit = {}, ) = EditUserProfileState( - userId = UserId("@john.doe:matrix.org"), - displayName = "John Doe", + userId = userId, + displayName = displayName, userAvatarUrl = userAvatarUrl, - avatarActions = persistentListOf(), - saveAction = AsyncAction.Uninitialized, - saveButtonEnabled = true, - cameraPermissionState = aPermissionsState(showDialog = false), - eventSink = {} + avatarActions = avatarActions.toImmutableList(), + saveButtonEnabled = saveButtonEnabled, + saveAction = saveAction, + cameraPermissionState = cameraPermissionState, + eventSink = eventSink, ) From 4a90186bd167f4bed1ea3fa670f2826b94519b7c Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 14:41:19 +0100 Subject: [PATCH 017/113] Add unit test on EditUserProfileView --- .../editprofile/EditUserProfileViewTest.kt | 136 ++++++++++++++++++ 1 file changed, 136 insertions(+) create mode 100644 features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileViewTest.kt diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileViewTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileViewTest.kt new file mode 100644 index 0000000000..f4c7144350 --- /dev/null +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileViewTest.kt @@ -0,0 +1,136 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2023-2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.preferences.impl.user.editprofile + +import androidx.activity.ComponentActivity +import androidx.compose.ui.test.junit4.AndroidComposeTestRule +import androidx.compose.ui.test.junit4.createAndroidComposeRule +import androidx.compose.ui.test.onNodeWithContentDescription +import androidx.compose.ui.test.onNodeWithText +import androidx.compose.ui.test.performClick +import androidx.test.ext.junit.runners.AndroidJUnit4 +import io.element.android.libraries.architecture.AsyncAction +import io.element.android.libraries.matrix.ui.media.AvatarAction +import io.element.android.libraries.ui.strings.CommonStrings +import io.element.android.tests.testutils.EnsureNeverCalled +import io.element.android.tests.testutils.EventsRecorder +import io.element.android.tests.testutils.clickOn +import io.element.android.tests.testutils.ensureCalledOnce +import io.element.android.tests.testutils.pressBack +import org.junit.Rule +import org.junit.Test +import org.junit.rules.TestRule +import org.junit.runner.RunWith + +@RunWith(AndroidJUnit4::class) +class EditUserProfileViewTest { + @get:Rule val rule = createAndroidComposeRule() + + @Test + fun `clicking on back emits the expected event`() { + val eventsRecorder = EventsRecorder() + rule.setEditUserProfileView( + aEditUserProfileState( + eventSink = eventsRecorder, + ), + ) + rule.pressBack() + eventsRecorder.assertSingle(EditUserProfileEvents.Exit) + } + + @Test + fun `clicking on cancel exit emits the expected event`() { + val eventsRecorder = EventsRecorder() + rule.setEditUserProfileView( + aEditUserProfileState( + saveAction = AsyncAction.ConfirmingCancellation, + eventSink = eventsRecorder, + ), + ) + rule.clickOn(CommonStrings.action_cancel) + eventsRecorder.assertSingle(EditUserProfileEvents.CloseDialog) + } + + @Test + fun `clicking on OK exit emits the expected event`() { + val eventsRecorder = EventsRecorder() + rule.setEditUserProfileView( + aEditUserProfileState( + saveAction = AsyncAction.ConfirmingCancellation, + eventSink = eventsRecorder, + ), + ) + rule.clickOn(CommonStrings.action_ok) + eventsRecorder.assertSingle(EditUserProfileEvents.Exit) + } + + @Test + fun `clicking on save emits the expected event`() { + val eventsRecorder = EventsRecorder() + rule.setEditUserProfileView( + aEditUserProfileState( + saveButtonEnabled = true, + saveAction = AsyncAction.Uninitialized, + eventSink = eventsRecorder, + ), + ) + rule.clickOn(CommonStrings.action_save) + eventsRecorder.assertSingle(EditUserProfileEvents.Save) + } + + @Test + fun `clicking on avatar opens the bottom sheet dialog`() { + val eventsRecorder = EventsRecorder() + val actions = listOf( + AvatarAction.TakePhoto, + AvatarAction.ChoosePhoto, + AvatarAction.Remove, + ) + rule.setEditUserProfileView( + aEditUserProfileState( + saveAction = AsyncAction.Uninitialized, + avatarActions = actions, + eventSink = eventsRecorder, + ), + ) + val contentDescription = rule.activity.getString(CommonStrings.a11y_avatar) + rule.onNodeWithContentDescription(contentDescription).performClick() + // Assert that the actions are displayed + actions.forEach { action -> + val text = rule.activity.getString(action.titleResId) + rule.onNodeWithText(text).assertExists() + } + } + + @Test + fun `success invokes the expected callback`() { + val eventsRecorder = EventsRecorder(expectEvents = false) + ensureCalledOnce { callback -> + rule.setEditUserProfileView( + aEditUserProfileState( + saveAction = AsyncAction.Success(Unit), + eventSink = eventsRecorder, + ), + onEditProfileSuccess = callback, + ) + } + } +} + +private fun AndroidComposeTestRule.setEditUserProfileView( + state: EditUserProfileState, + onEditProfileSuccess: () -> Unit = EnsureNeverCalled(), +) { + setContent { + EditUserProfileView( + state = state, + onEditProfileSuccess = onEditProfileSuccess, + ) + } +} From f05a00b9b3da95b7e7cfcf8eecf84b1e3fe4004e Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 15:13:23 +0100 Subject: [PATCH 018/113] Avoid using navigateUp. --- .../preferences/impl/PreferencesFlowNode.kt | 4 +++- .../user/editprofile/EditUserProfileNode.kt | 8 ++++---- .../architecture/navigation/BaseCallback.kt | 17 +++++++++++++++++ .../architecture/navigation/BaseNavigator.kt | 3 +++ 4 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseCallback.kt diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt index bd43736cbd..5d4e55e888 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt @@ -40,6 +40,7 @@ import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.appyx.canPop import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.createNode +import io.element.android.libraries.architecture.navigation.BaseCallback import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId @@ -267,7 +268,8 @@ class PreferencesFlowNode( } is NavTarget.UserProfile -> { val inputs = EditUserProfileNode.Inputs(navTarget.matrixUser) - createNode(buildContext, listOf(inputs)) + val callback = BaseCallback { backstack.pop() } + createNode(buildContext, listOf(inputs, callback)) } NavTarget.LockScreenSettings -> { lockScreenEntryPoint.createNode( diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt index 3d939cfbd4..dcbdc14031 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt @@ -17,7 +17,9 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode import io.element.android.libraries.architecture.NodeInputs +import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.inputs +import io.element.android.libraries.architecture.navigation.BaseCallback import io.element.android.libraries.architecture.navigation.BaseNavigator import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.user.MatrixUser @@ -35,6 +37,7 @@ class EditUserProfileNode( ) : NodeInputs val matrixUser = inputs().matrixUser + val callback: BaseCallback = callback() val presenter = presenterFactory.create( matrixUser = matrixUser, navigator = this, @@ -50,8 +53,5 @@ class EditUserProfileNode( ) } - override fun close() { - // TODO Invoke callback - navigateUp() - } + override fun close() = callback.onDone() } diff --git a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseCallback.kt b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseCallback.kt new file mode 100644 index 0000000000..13b102b46d --- /dev/null +++ b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseCallback.kt @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.architecture.navigation + +import com.bumble.appyx.core.plugin.Plugin + +/** + * Base callback interface to be implemented by callers to handle results from nodes. + */ +fun interface BaseCallback : Plugin { + fun onDone() +} diff --git a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseNavigator.kt b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseNavigator.kt index 5cc61166fe..e5dec55c89 100644 --- a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseNavigator.kt +++ b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseNavigator.kt @@ -7,6 +7,9 @@ package io.element.android.libraries.architecture.navigation +/** + * Base navigator interface to be implemented by nodes to handle navigation actions from presenters. + */ fun interface BaseNavigator { fun close() } From 2e2a5020a77e0d3e78cf2a7f0f3a274d402dca4d Mon Sep 17 00:00:00 2001 From: ElementBot Date: Fri, 21 Nov 2025 14:29:04 +0000 Subject: [PATCH 019/113] Update screenshots --- ...nces.impl.user.editprofile_EditUserProfileView_Day_2_en.png | 3 +++ ...es.impl.user.editprofile_EditUserProfileView_Night_2_en.png | 3 +++ 2 files changed, 6 insertions(+) create mode 100644 tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png new file mode 100644 index 0000000000..1e81e0e58a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:da49d0867fdaa28fbe7db7dc21c5de09268e7bb3afdb0b2289df372d537c2abb +size 33570 diff --git a/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png new file mode 100644 index 0000000000..73a68c1db0 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:60fe1926cf8d66a8086268f3e4e1b6b1616f860668e1e5f4dc670d5c57ec4d24 +size 31943 From 942d60812e415ebbb672237655fc34380c8d36d7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 15:46:10 +0100 Subject: [PATCH 020/113] Remove BaseCallback, it's actually not ideal when looking for usage. --- .../preferences/impl/PreferencesFlowNode.kt | 7 +++++-- .../user/editprofile/EditUserProfileNode.kt | 7 +++++-- .../architecture/navigation/BaseCallback.kt | 17 ----------------- 3 files changed, 10 insertions(+), 21 deletions(-) delete mode 100644 libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseCallback.kt diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt index 5d4e55e888..783d732036 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt @@ -40,7 +40,6 @@ import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.appyx.canPop import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.createNode -import io.element.android.libraries.architecture.navigation.BaseCallback import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId @@ -268,7 +267,11 @@ class PreferencesFlowNode( } is NavTarget.UserProfile -> { val inputs = EditUserProfileNode.Inputs(navTarget.matrixUser) - val callback = BaseCallback { backstack.pop() } + val callback = object : EditUserProfileNode.Callback { + override fun onDone() { + backstack.pop() + } + } createNode(buildContext, listOf(inputs, callback)) } NavTarget.LockScreenSettings -> { diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt index dcbdc14031..27adc2e32e 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt @@ -19,7 +19,6 @@ import io.element.android.annotations.ContributesNode import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.inputs -import io.element.android.libraries.architecture.navigation.BaseCallback import io.element.android.libraries.architecture.navigation.BaseNavigator import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.user.MatrixUser @@ -36,8 +35,12 @@ class EditUserProfileNode( val matrixUser: MatrixUser ) : NodeInputs + interface Callback : Plugin { + fun onDone() + } + val matrixUser = inputs().matrixUser - val callback: BaseCallback = callback() + val callback: Callback = callback() val presenter = presenterFactory.create( matrixUser = matrixUser, navigator = this, diff --git a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseCallback.kt b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseCallback.kt deleted file mode 100644 index 13b102b46d..0000000000 --- a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseCallback.kt +++ /dev/null @@ -1,17 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.libraries.architecture.navigation - -import com.bumble.appyx.core.plugin.Plugin - -/** - * Base callback interface to be implemented by callers to handle results from nodes. - */ -fun interface BaseCallback : Plugin { - fun onDone() -} From 31e9abbb980a64d1f2316b6c0aeadd7f4003769a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 15:50:42 +0100 Subject: [PATCH 021/113] Remove BaseNavigator, it's actually not ideal when looking for usage. --- .../user/editprofile/EditUserProfileNavigator.kt | 7 ++----- .../impl/user/editprofile/EditUserProfileNode.kt | 3 +-- .../user/editprofile/EditUserProfilePresenter.kt | 5 ++--- .../editprofile/EditUserProfilePresenterTest.kt | 8 +++----- .../editprofile/FakeEditUserProfileNavigator.kt | 16 ++++++++++++++++ 5 files changed, 24 insertions(+), 15 deletions(-) rename libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseNavigator.kt => features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNavigator.kt (52%) create mode 100644 features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/FakeEditUserProfileNavigator.kt diff --git a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseNavigator.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNavigator.kt similarity index 52% rename from libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseNavigator.kt rename to features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNavigator.kt index e5dec55c89..2935bce747 100644 --- a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/navigation/BaseNavigator.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNavigator.kt @@ -5,11 +5,8 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.libraries.architecture.navigation +package io.element.android.features.preferences.impl.user.editprofile -/** - * Base navigator interface to be implemented by nodes to handle navigation actions from presenters. - */ -fun interface BaseNavigator { +interface EditUserProfileNavigator { fun close() } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt index 27adc2e32e..2303abb06e 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfileNode.kt @@ -19,7 +19,6 @@ import io.element.android.annotations.ContributesNode import io.element.android.libraries.architecture.NodeInputs import io.element.android.libraries.architecture.callback import io.element.android.libraries.architecture.inputs -import io.element.android.libraries.architecture.navigation.BaseNavigator import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.user.MatrixUser @@ -30,7 +29,7 @@ class EditUserProfileNode( @Assisted plugins: List, presenterFactory: EditUserProfilePresenter.Factory, ) : Node(buildContext, plugins = plugins), - BaseNavigator { + EditUserProfileNavigator { data class Inputs( val matrixUser: MatrixUser ) : NodeInputs diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt index 46298c96a2..59607139d7 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenter.kt @@ -26,7 +26,6 @@ import dev.zacsweers.metro.AssistedInject import io.element.android.libraries.androidutils.file.TemporaryUriDeleter import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter -import io.element.android.libraries.architecture.navigation.BaseNavigator import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.core.mimetype.MimeTypes @@ -46,7 +45,7 @@ import timber.log.Timber @AssistedInject class EditUserProfilePresenter( @Assisted private val matrixUser: MatrixUser, - @Assisted private val navigator: BaseNavigator, + @Assisted private val navigator: EditUserProfileNavigator, private val matrixClient: MatrixClient, private val mediaPickerProvider: PickerProvider, private val mediaPreProcessor: MediaPreProcessor, @@ -61,7 +60,7 @@ class EditUserProfilePresenter( interface Factory { fun create( matrixUser: MatrixUser, - navigator: BaseNavigator, + navigator: EditUserProfileNavigator, ): EditUserProfilePresenter } diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt index a39b2013b6..3432bac29f 100644 --- a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/EditUserProfilePresenterTest.kt @@ -12,7 +12,6 @@ import android.net.Uri import com.google.common.truth.Truth.assertThat import io.element.android.libraries.androidutils.file.TemporaryUriDeleter import io.element.android.libraries.architecture.AsyncAction -import io.element.android.libraries.architecture.navigation.BaseNavigator import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.user.MatrixUser import io.element.android.libraries.matrix.test.AN_AVATAR_URL @@ -31,7 +30,6 @@ import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.consumeItemsUntilPredicate import io.element.android.tests.testutils.consumeItemsUntilTimeout import io.element.android.tests.testutils.fake.FakeTemporaryUriDeleter -import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.lambda.lambdaRecorder import io.element.android.tests.testutils.lambda.value import io.element.android.tests.testutils.test @@ -79,7 +77,7 @@ class EditUserProfilePresenterTest { private fun createEditUserProfilePresenter( matrixClient: MatrixClient = FakeMatrixClient(), - navigator: BaseNavigator = BaseNavigator { lambdaError() }, + navigator: EditUserProfileNavigator = FakeEditUserProfileNavigator(), matrixUser: MatrixUser = aMatrixUser(), permissionsPresenter: PermissionsPresenter = FakePermissionsPresenter(), temporaryUriDeleter: TemporaryUriDeleter = FakeTemporaryUriDeleter(), @@ -122,7 +120,7 @@ class EditUserProfilePresenterTest { val closeLambda = lambdaRecorder {} val presenter = createEditUserProfilePresenter( matrixUser = user, - navigator = BaseNavigator { closeLambda() }, + navigator = FakeEditUserProfileNavigator(closeLambda), ) presenter.test { val initialState = awaitItem() @@ -137,7 +135,7 @@ class EditUserProfilePresenterTest { val closeLambda = lambdaRecorder {} val presenter = createEditUserProfilePresenter( matrixUser = user, - navigator = BaseNavigator { closeLambda() }, + navigator = FakeEditUserProfileNavigator(closeLambda), ) presenter.test { val initialState = awaitItem() diff --git a/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/FakeEditUserProfileNavigator.kt b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/FakeEditUserProfileNavigator.kt new file mode 100644 index 0000000000..7b34e904a1 --- /dev/null +++ b/features/preferences/impl/src/test/kotlin/io/element/android/features/preferences/impl/user/editprofile/FakeEditUserProfileNavigator.kt @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.preferences.impl.user.editprofile + +import io.element.android.tests.testutils.lambda.lambdaError + +class FakeEditUserProfileNavigator( + val closeLambda: () -> Unit = { lambdaError() } +) : EditUserProfileNavigator { + override fun close() = closeLambda() +} From e475a969d78076b22f7c9528a3c6142f08e5f492 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 15:42:15 +0100 Subject: [PATCH 022/113] Fix crash when clicking fast on back key on the Add account screen. --- .../kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt | 5 +++++ .../main/kotlin/io/element/android/appnav/RootFlowNode.kt | 4 ++++ .../io/element/android/features/login/api/LoginEntryPoint.kt | 1 + .../io/element/android/features/login/impl/LoginFlowNode.kt | 4 ++++ .../features/login/impl/screens/onboarding/OnBoardingNode.kt | 3 ++- 5 files changed, 16 insertions(+), 1 deletion(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt index 2544abbfb3..d888ac3b15 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt @@ -57,6 +57,7 @@ class NotLoggedInFlowNode( interface Callback : Plugin { fun navigateToBugReport() + fun onDone() } private val callback: Callback = callback() @@ -83,6 +84,10 @@ class NotLoggedInFlowNode( override fun navigateToBugReport() { callback.navigateToBugReport() } + + override fun onDone() { + callback.onDone() + } } loginEntryPoint.createNode( parentNode = this, diff --git a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt index a0d2f44640..1a23bce132 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt @@ -243,6 +243,10 @@ class RootFlowNode( override fun navigateToBugReport() { backstack.push(NavTarget.BugReport) } + + override fun onDone() { + backstack.pop() + } } val params = NotLoggedInFlowNode.Params( loginParams = navTarget.params, diff --git a/features/login/api/src/main/kotlin/io/element/android/features/login/api/LoginEntryPoint.kt b/features/login/api/src/main/kotlin/io/element/android/features/login/api/LoginEntryPoint.kt index 5256bcb695..830a63b8f1 100644 --- a/features/login/api/src/main/kotlin/io/element/android/features/login/api/LoginEntryPoint.kt +++ b/features/login/api/src/main/kotlin/io/element/android/features/login/api/LoginEntryPoint.kt @@ -21,6 +21,7 @@ interface LoginEntryPoint : FeatureEntryPoint { interface Callback : Plugin { fun navigateToBugReport() + fun onDone() } fun createNode( diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/LoginFlowNode.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/LoginFlowNode.kt index 4a7275e2da..a19bb12d86 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/LoginFlowNode.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/LoginFlowNode.kt @@ -167,6 +167,10 @@ class LoginFlowNode( override fun navigateToLoginPassword() { backstack.push(NavTarget.LoginPassword) } + + override fun onDone() { + callback.onDone() + } } val params = inputs() val inputs = OnBoardingNode.Params( diff --git a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingNode.kt b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingNode.kt index 7e0901470a..1ded677c13 100644 --- a/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingNode.kt +++ b/features/login/impl/src/main/kotlin/io/element/android/features/login/impl/screens/onboarding/OnBoardingNode.kt @@ -42,6 +42,7 @@ class OnBoardingNode( fun navigateToLoginPassword() fun navigateToOidc(oidcDetails: OidcDetails) fun navigateToCreateAccount(url: String) + fun onDone() } data class Params( @@ -71,7 +72,7 @@ class OnBoardingNode( onNeedLoginPassword = callback::navigateToLoginPassword, onLearnMoreClick = { openLearnMorePage(context) }, onCreateAccountContinue = callback::navigateToCreateAccount, - onBackClick = ::navigateUp, + onBackClick = callback::onDone, ) } } From 7bf7f68706479cc6bbfc87bea6c5165c39feb079 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 15:52:54 +0100 Subject: [PATCH 023/113] Fix crash when clicking fast on back key on the Labs screen. --- .../features/preferences/impl/PreferencesFlowNode.kt | 7 ++++++- .../features/preferences/impl/labs/LabsNode.kt | 12 +++++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt index 783d732036..d316006bae 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt @@ -190,7 +190,12 @@ class PreferencesFlowNode( createNode(buildContext, listOf(developerSettingsCallback)) } NavTarget.Labs -> { - createNode(buildContext) + val callback = object : LabsNode.Callback { + override fun onDone() { + backstack.pop() + } + } + createNode(buildContext, listOf(callback)) } NavTarget.About -> { val callback = object : AboutNode.Callback { diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsNode.kt index 343b4d2795..b7ba73c9af 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/labs/LabsNode.kt @@ -16,6 +16,7 @@ import com.bumble.appyx.core.plugin.Plugin import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode +import io.element.android.libraries.architecture.callback import io.element.android.libraries.di.SessionScope @ContributesNode(SessionScope::class) @@ -25,9 +26,18 @@ class LabsNode( @Assisted plugins: List, private val presenter: LabsPresenter, ) : Node(buildContext, plugins = plugins) { + interface Callback : Plugin { + fun onDone() + } + + val callback: Callback = callback() + @Composable override fun View(modifier: Modifier) { val state = presenter.present() - LabsView(state = state, onBack = ::navigateUp) + LabsView( + state = state, + onBack = callback::onDone, + ) } } From 83d13d0eb5c64b18355a95b7c4c7bd54d19fa465 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 15:54:03 +0100 Subject: [PATCH 024/113] Fix crash when clicking fast on back key on the Developer settings screen. --- .../android/features/preferences/impl/PreferencesFlowNode.kt | 4 ++++ .../preferences/impl/developer/DeveloperSettingsNode.kt | 3 ++- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt index d316006bae..c7328fb6ed 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/PreferencesFlowNode.kt @@ -186,6 +186,10 @@ class PreferencesFlowNode( override fun navigateToPushHistory() { backstack.push(NavTarget.PushHistory) } + + override fun onDone() { + backstack.pop() + } } createNode(buildContext, listOf(developerSettingsCallback)) } diff --git a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsNode.kt b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsNode.kt index 71077fe405..98c7d89633 100644 --- a/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsNode.kt +++ b/features/preferences/impl/src/main/kotlin/io/element/android/features/preferences/impl/developer/DeveloperSettingsNode.kt @@ -31,6 +31,7 @@ class DeveloperSettingsNode( ) : Node(buildContext, plugins = plugins) { interface Callback : Plugin { fun navigateToPushHistory() + fun onDone() } private val callback: Callback = callback() @@ -49,7 +50,7 @@ class DeveloperSettingsNode( modifier = modifier, onOpenShowkase = ::openShowkase, onPushHistoryClick = callback::navigateToPushHistory, - onBackClick = ::navigateUp + onBackClick = callback::onDone, ) } } From b15c5507c58353f29caf05e3290e291881ec58e7 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 16:22:33 +0100 Subject: [PATCH 025/113] Fix compilation issue in test --- .../android/features/login/impl/DefaultLoginEntryPointTest.kt | 1 + 1 file changed, 1 insertion(+) diff --git a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/DefaultLoginEntryPointTest.kt b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/DefaultLoginEntryPointTest.kt index 9d72edebc9..953693b40d 100644 --- a/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/DefaultLoginEntryPointTest.kt +++ b/features/login/impl/src/test/kotlin/io/element/android/features/login/impl/DefaultLoginEntryPointTest.kt @@ -43,6 +43,7 @@ class DefaultLoginEntryPointTest { } val callback = object : LoginEntryPoint.Callback { override fun navigateToBugReport() = lambdaError() + override fun onDone() = lambdaError() } val params = LoginEntryPoint.Params( accountProvider = "ac", From c10bea08b26c83b22f98abcacdb06bce0503689b Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Fri, 21 Nov 2025 16:36:56 +0100 Subject: [PATCH 026/113] Fix test --- .../impl/roles/ChangeRolesViewTest.kt | 46 ++++++++----------- 1 file changed, 19 insertions(+), 27 deletions(-) diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesViewTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesViewTest.kt index 63fa9f3b19..fd45e5408c 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesViewTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesViewTest.kt @@ -50,7 +50,6 @@ class ChangeRolesViewTest { ), ) }.exceptionOrNull() - assertThat(exception).isNotNull() } @@ -63,9 +62,7 @@ class ChangeRolesViewTest { eventSink = eventsRecorder, ), ) - rule.pressBackKey() - eventsRecorder.assertSingle(ChangeRolesEvent.ToggleSearchActive) } @@ -78,9 +75,7 @@ class ChangeRolesViewTest { eventSink = eventsRecorder, ), ) - rule.pressBackKey() - eventsRecorder.assertList(listOf(ChangeRolesEvent.QueryChanged(""), ChangeRolesEvent.Exit)) } @@ -93,9 +88,7 @@ class ChangeRolesViewTest { eventSink = eventsRecorder, ), ) - rule.pressBack() - eventsRecorder.assertList(listOf(ChangeRolesEvent.QueryChanged(""), ChangeRolesEvent.Exit)) } @@ -108,9 +101,7 @@ class ChangeRolesViewTest { eventSink = eventsRecorder, ), ) - rule.clickOn(CommonStrings.action_save) - eventsRecorder.assertList(listOf(ChangeRolesEvent.QueryChanged(""), ChangeRolesEvent.Save)) } @@ -123,9 +114,7 @@ class ChangeRolesViewTest { eventSink = eventsRecorder, ), ) - rule.clickOn(CommonStrings.action_save) - eventsRecorder.assertList(listOf(ChangeRolesEvent.QueryChanged(""))) } @@ -139,9 +128,7 @@ class ChangeRolesViewTest { eventSink = eventsRecorder, ), ) - rule.clickOn(CommonStrings.action_ok) - eventsRecorder.assertSingle(ChangeRolesEvent.Exit) } @@ -155,26 +142,22 @@ class ChangeRolesViewTest { eventSink = eventsRecorder, ), ) - rule.clickOn(CommonStrings.action_cancel) - eventsRecorder.assertSingle(ChangeRolesEvent.CloseDialog) } @Test - fun `save confirmation dialog - submit saves the changes`() { + fun `save admins confirmation dialog - submit saves the changes`() { val eventsRecorder = EventsRecorder() rule.setChangeRolesContent( state = aChangeRolesState( role = RoomMember.Role.Admin, isSearchActive = true, - savingState = AsyncAction.ConfirmingNoParams, + savingState = ConfirmingModifyingAdmins, eventSink = eventsRecorder, ), ) - rule.clickOn(CommonStrings.action_ok) - eventsRecorder.assertSingle(ChangeRolesEvent.Save) } @@ -185,30 +168,41 @@ class ChangeRolesViewTest { state = aChangeRolesState( role = RoomMember.Role.Owner(isCreator = false), isSearchActive = true, - savingState = AsyncAction.ConfirmingNoParams, + savingState = ConfirmingModifyingOwners, eventSink = eventsRecorder, ), ) - rule.clickOn(CommonStrings.action_continue) - eventsRecorder.assertSingle(ChangeRolesEvent.Save) } @Test - fun `save confirmation dialog - cancel removes the dialog`() { + fun `save admins confirmation dialog - cancel removes the dialog`() { val eventsRecorder = EventsRecorder() rule.setChangeRolesContent( state = aChangeRolesState( role = RoomMember.Role.Admin, isSearchActive = true, - savingState = AsyncAction.ConfirmingNoParams, + savingState = ConfirmingModifyingAdmins, eventSink = eventsRecorder, ), ) - rule.clickOn(CommonStrings.action_cancel) + eventsRecorder.assertSingle(ChangeRolesEvent.CloseDialog) + } + @Test + fun `save owners confirmation dialog - cancel removes the dialog`() { + val eventsRecorder = EventsRecorder() + rule.setChangeRolesContent( + state = aChangeRolesState( + role = RoomMember.Role.Owner(isCreator = false), + isSearchActive = true, + savingState = ConfirmingModifyingOwners, + eventSink = eventsRecorder, + ), + ) + rule.clickOn(CommonStrings.action_cancel) eventsRecorder.assertSingle(ChangeRolesEvent.CloseDialog) } @@ -222,9 +216,7 @@ class ChangeRolesViewTest { eventSink = eventsRecorder, ), ) - rule.clickOn(CommonStrings.action_ok) - eventsRecorder.assertSingle(ChangeRolesEvent.CloseDialog) } From 378fe32fdefdc9d03e8a1cf907cdd3673b2a51c1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 21 Nov 2025 16:51:56 +0100 Subject: [PATCH 027/113] fix(deps): update dependency androidx.sqlite:sqlite-ktx to v2.6.2 (#5769) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 2d291ed9f3..3a5ac4046d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -201,7 +201,7 @@ sqldelight-driver-android = { module = "app.cash.sqldelight:android-driver", ver sqldelight-driver-jvm = { module = "app.cash.sqldelight:sqlite-driver", version.ref = "sqldelight" } sqldelight-coroutines = { module = "app.cash.sqldelight:coroutines-extensions", version.ref = "sqldelight" } sqlcipher = "net.zetetic:sqlcipher-android:4.11.0" -sqlite = "androidx.sqlite:sqlite-ktx:2.6.1" +sqlite = "androidx.sqlite:sqlite-ktx:2.6.2" unifiedpush = "org.unifiedpush.android:connector:3.1.2" vanniktech_blurhash = "com.vanniktech:blurhash:0.3.0" telephoto_zoomableimage = { module = "me.saket.telephoto:zoomable-image-coil", version.ref = "telephoto" } From 78c19eb1eb15278e8eb53004e01b2e08c01857b8 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 21 Nov 2025 15:27:43 +0100 Subject: [PATCH 028/113] Setting version for the release 25.11.3 --- plugins/src/main/kotlin/Versions.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/src/main/kotlin/Versions.kt b/plugins/src/main/kotlin/Versions.kt index 72983c28df..863b3ec79f 100644 --- a/plugins/src/main/kotlin/Versions.kt +++ b/plugins/src/main/kotlin/Versions.kt @@ -45,7 +45,7 @@ private const val versionMonth = 11 * Release number in the month. Value must be in [0,99]. * Do not update this value. it is updated by the release script. */ -private const val versionReleaseNumber = 2 +private const val versionReleaseNumber = 3 object Versions { /** From e2c08b501cab970cd896de26747d6c946ab7ec8a Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 21 Nov 2025 15:27:45 +0100 Subject: [PATCH 029/113] Adding fastlane file for version 25.11.3 --- fastlane/metadata/android/en-US/changelogs/202511030.txt | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 fastlane/metadata/android/en-US/changelogs/202511030.txt diff --git a/fastlane/metadata/android/en-US/changelogs/202511030.txt b/fastlane/metadata/android/en-US/changelogs/202511030.txt new file mode 100644 index 0000000000..a4b397f1bb --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/202511030.txt @@ -0,0 +1,2 @@ +Main changes in this version: bug fixes and improvements. +Full changelog: https://github.com/element-hq/element-x-android/releases \ No newline at end of file From e124e76fb2a58fa4826d2469ef1329f3e8195b2e Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 21 Nov 2025 16:51:36 +0100 Subject: [PATCH 030/113] Changelog for version 25.11.3 --- CHANGES.md | 80 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 80 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 28e774a8ff..01a83c0ccf 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,83 @@ +Changes in Element X v25.11.3 +============================= + + + +## What's Changed +### 🙌 Improvements +* Improve rendering notification for multi account by @bmarty in https://github.com/element-hq/element-x-android/pull/5645 +* Change : roles and permissions by @ganfra in https://github.com/element-hq/element-x-android/pull/5685 +* Improve account provider selection during the login flow by @bmarty in https://github.com/element-hq/element-x-android/pull/5692 +* Let notifications use avatar fallback. by @bmarty in https://github.com/element-hq/element-x-android/pull/5721 +* Changes : member list improvements by @ganfra in https://github.com/element-hq/element-x-android/pull/5728 +### 🐛 Bugfixes +* Do not use the bestDescription but the caption for images, when available by @bmarty in https://github.com/element-hq/element-x-android/pull/5684 +* Add the user certificate if any when creating Matrix Client. by @bmarty in https://github.com/element-hq/element-x-android/pull/5686 +* Ensure the form data are not lost when opening the log viewer. by @bmarty in https://github.com/element-hq/element-x-android/pull/5695 +* Fix password flow when using a login link by @bmarty in https://github.com/element-hq/element-x-android/pull/5693 +* Fix layout issue in text composer by @bmarty in https://github.com/element-hq/element-x-android/pull/5710 +* Fix navigation stack overflow when sharing media by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5724 +* Notification robustness by @bmarty in https://github.com/element-hq/element-x-android/pull/5726 +* Send read receipts using the current timeline, not the live timeline by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5731 +* Render Owner in the horizontal list when editing Admins. by @bmarty in https://github.com/element-hq/element-x-android/pull/5736 +* Stop overriding the homeserver when restoring a `Client` by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5753 +* Revert "Stop overriding the homeserver when restoring a `Client`" by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5754 +* Try fixing forced dark mode issues on MIUI on Android 10 by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5708 +* Fix crash at startup by @bmarty in https://github.com/element-hq/element-x-android/pull/5761 +* Fix null pointer exception on room notification settings. by @bmarty in https://github.com/element-hq/element-x-android/pull/5758 +* Fix crash when viewing Pinned events by @bmarty in https://github.com/element-hq/element-x-android/pull/5764 +* Fix crash when pressing back from the showkase Activity by @bmarty in https://github.com/element-hq/element-x-android/pull/5772 +* Fix navigation issue once incoming share is handled by @bmarty in https://github.com/element-hq/element-x-android/pull/5773 +* Fix crash in work manager by @bmarty in https://github.com/element-hq/element-x-android/pull/5768 +### 🗣 Translations +* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/5704 +* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/5747 +* Sync Strings by @ElementBot in https://github.com/element-hq/element-x-android/pull/5782 +### 🧱 Build +* Module cleanup by @bmarty in https://github.com/element-hq/element-x-android/pull/5722 +* Add `NIGHTLY` env for Sentry by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5779 +### 🚧 In development 🚧 +* Space : prepare Space Settings screen by @ganfra in https://github.com/element-hq/element-x-android/pull/5668 +### Dependency upgrades +* fix(deps): update dependency androidx.core:core-splashscreen to v1.2.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5687 +* fix(deps): update dependency com.posthog:posthog-android to v3.26.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5696 +* fix(deps): update metro to v0.7.5 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5697 +* Update dependency org.matrix.rustcomponents:sdk-android to v25.11.11 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5716 +* Update plugin ktlint to v14 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5713 +* Update plugin dependencycheck to v12.1.9 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5717 +* Update dependency org.maplibre.gl:android-sdk to v12.1.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5714 +* Update dependency io.sentry:sentry-android to v8.26.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5720 +* Update sqldelight to v2.2.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5730 +* fix(deps): update dependency com.squareup.okhttp3:okhttp-bom to v5.3.1 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5746 +* fix(deps): update dependency com.google.firebase:firebase-bom to v34.6.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5737 +* fix(deps): update metro to v0.7.6 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5752 +* fix(deps): update dependency org.maplibre.gl:android-sdk to v12.1.3 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5743 +* Update dependency com.squareup.okhttp3:okhttp-bom to v5.3.2 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5757 +* fix(deps): update dependency com.pinterest.ktlint:ktlint-cli to v1.8.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5738 +* fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.11.19 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5762 +* fix(deps): update dependencyanalysis to v3.5.0 by @renovate[bot] in https://github.com/element-hq/element-x-android/pull/5776 +### Others +* Extract save change dialog by @bmarty in https://github.com/element-hq/element-x-android/pull/5679 +* Use the dedicated subdomain for the bug report URL by default by @benbz in https://github.com/element-hq/element-x-android/pull/5689 +* Convert `ComposerAlertMolecule` to use alert levels. by @kaylendog in https://github.com/element-hq/element-x-android/pull/5691 +* Improve composer alert molecule by @bmarty in https://github.com/element-hq/element-x-android/pull/5701 +* Code consistency around view event handling by @bmarty in https://github.com/element-hq/element-x-android/pull/5698 +* Update copyright holders by @bmarty in https://github.com/element-hq/element-x-android/pull/5706 +* Fix rendering notifications after receiving redundant push by @SpiritCroc in https://github.com/element-hq/element-x-android/pull/5711 +* Fix push gateway with some push provider (Sunup/autopush) by @p1gp1g in https://github.com/element-hq/element-x-android/pull/5741 +* Use new notification sound in release. by @bmarty in https://github.com/element-hq/element-x-android/pull/5748 +* Fix issue on brand color override by @bmarty in https://github.com/element-hq/element-x-android/pull/5626 +* Add media retention policy by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5749 +* Enable logging OkHttp traffic based on the current log level by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5750 +* Remove unused `slidingSyncProxy` from DB. by @bmarty in https://github.com/element-hq/element-x-android/pull/5755 +* Add some performance metrics for Sentry by @jmartinesp in https://github.com/element-hq/element-x-android/pull/5760 + +## New Contributors +* @benbz made their first contribution in https://github.com/element-hq/element-x-android/pull/5689 +* @kaylendog made their first contribution in https://github.com/element-hq/element-x-android/pull/5691 + +**Full Changelog**: https://github.com/element-hq/element-x-android/compare/v25.11.2...v25.11.3 + Changes in Element X v25.11.2 ============================= From 95c9e768f41253c63f7cb8f3f614b1b488d43fb4 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Fri, 21 Nov 2025 17:01:01 +0100 Subject: [PATCH 031/113] Use regex to check forbidden terms. (#5784) We were returning and `Elementul` as a match for the forbidden term `Element`. It now checks for the full word. --- tools/localazy/checkForbiddenTerms.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/tools/localazy/checkForbiddenTerms.py b/tools/localazy/checkForbiddenTerms.py index d108d19e4f..e190fcea68 100755 --- a/tools/localazy/checkForbiddenTerms.py +++ b/tools/localazy/checkForbiddenTerms.py @@ -6,6 +6,7 @@ # SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. # Please see LICENSE files in the repository root for full details. +import re import sys from xml.dom import minidom @@ -14,7 +15,7 @@ file = sys.argv[1] # Dict of forbidden terms, with exceptions for some String name # Keys are the terms, values are the exceptions. forbiddenTerms = { - "Element": [ + r"\bElement\b": [ # Those 2 strings are only used in debug version "screen_advanced_settings_element_call_base_url", "screen_advanced_settings_element_call_base_url_description", @@ -48,7 +49,8 @@ for elem in content.getElementsByTagName('string'): value = child.nodeValue # If value contains a forbidden term, add the error to errors for (term, exceptions) in forbiddenTerms.items(): - if term in value and name not in exceptions: + matches = re.search(term, value) + if matches and name not in exceptions: errors.append('Forbidden term "' + term + '" in string: "' + name + '": ' + value) ### Plurals @@ -65,7 +67,8 @@ for elem in content.getElementsByTagName('plurals'): value = child.nodeValue # If value contains a forbidden term, add the error to errors for (term, exceptions) in forbiddenTerms.items(): - if term in value and name not in exceptions: + matches = re.search(term, value) + if matches and name not in exceptions: errors.append('Forbidden term "' + term + '" in plural: "' + name + '": ' + value) # If errors is not empty print the report From 16a8425ab618828b5f7127509c650d024f62cdf9 Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 20 Nov 2025 16:41:43 +0100 Subject: [PATCH 032/113] change(members): make sure state is not lost when navigating --- .../impl/members/RoomMemberListEvents.kt | 1 + .../impl/members/RoomMemberListNode.kt | 6 +- .../impl/members/RoomMemberListPresenter.kt | 18 +- .../impl/members/RoomMemberListState.kt | 6 + .../members/RoomMemberListStateProvider.kt | 207 ++++++++++-------- .../impl/members/RoomMemberListView.kt | 40 +--- 6 files changed, 153 insertions(+), 125 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt index 00332e391a..9a8798124e 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt @@ -11,6 +11,7 @@ package io.element.android.features.roomdetails.impl.members import io.element.android.libraries.matrix.api.room.RoomMember sealed interface RoomMemberListEvents { + data class ChangeSelectedSection(val section: SelectedSection): RoomMemberListEvents data class UpdateSearchQuery(val query: String) : RoomMemberListEvents data class OnSearchActiveChanged(val active: Boolean) : RoomMemberListEvents data class RoomMemberSelected(val roomMember: RoomMember) : RoomMemberListEvents diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListNode.kt index 4d915aa294..750b111fc3 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListNode.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListNode.kt @@ -9,6 +9,8 @@ package io.element.android.features.roomdetails.impl.members import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import com.bumble.appyx.core.lifecycle.subscribe import com.bumble.appyx.core.modality.BuildContext @@ -21,6 +23,7 @@ import io.element.android.annotations.ContributesNode import io.element.android.features.roommembermoderation.api.ModerationAction import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents import io.element.android.features.roommembermoderation.api.RoomMemberModerationRenderer +import io.element.android.libraries.architecture.appyx.launchMolecule import io.element.android.libraries.architecture.callback import io.element.android.libraries.di.RoomScope import io.element.android.libraries.matrix.api.core.UserId @@ -41,6 +44,7 @@ class RoomMemberListNode( } private val callback: Callback = callback() + private val stateFlow = launchMolecule { presenter.present() } init { lifecycle.subscribe( @@ -64,7 +68,7 @@ class RoomMemberListNode( @Composable override fun View(modifier: Modifier) { - val state = presenter.present() + val state by stateFlow.collectAsState() RoomMemberListView( state = state, modifier = modifier, diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt index e69ddb744a..65385e5f08 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt @@ -10,6 +10,7 @@ package io.element.android.features.roomdetails.impl.members import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect +import androidx.compose.runtime.SideEffect import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableStateOf @@ -18,7 +19,7 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.saveable.rememberSaveable import androidx.compose.runtime.setValue import dev.zacsweers.metro.Inject -import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents +import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents.ShowActionsForUser import io.element.android.features.roommembermoderation.api.RoomMemberModerationState import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter @@ -53,7 +54,7 @@ class RoomMemberListPresenter( private val roomMembersModerationPresenter: Presenter, private val encryptionService: EncryptionService, ) : Presenter { - private var roomMembers: AsyncData by mutableStateOf(AsyncData.Loading()) + private val powerLevelRoomMemberComparator = PowerLevelRoomMemberComparator() @Composable @@ -77,6 +78,9 @@ class RoomMemberListPresenter( .launchIn(this) } + var roomMembers: AsyncData by remember { mutableStateOf(AsyncData.Loading())} + var selectedSection by remember { mutableStateOf(SelectedSection.MEMBERS)} + // Update the room members when the screen is loaded LaunchedEffect(Unit) { room.updateMembers() @@ -160,7 +164,14 @@ class RoomMemberListPresenter( is RoomMemberListEvents.OnSearchActiveChanged -> isSearchActive = event.active is RoomMemberListEvents.UpdateSearchQuery -> searchQuery = event.query is RoomMemberListEvents.RoomMemberSelected -> - roomModerationState.eventSink(RoomMemberModerationEvents.ShowActionsForUser(event.roomMember.toMatrixUser())) + roomModerationState.eventSink(ShowActionsForUser(event.roomMember.toMatrixUser())) + is RoomMemberListEvents.ChangeSelectedSection -> selectedSection = event.section + } + } + + if (!roomModerationState.canBan && selectedSection == SelectedSection.BANNED) { + SideEffect { + selectedSection = SelectedSection.MEMBERS } } @@ -171,6 +182,7 @@ class RoomMemberListPresenter( isSearchActive = isSearchActive, canInvite = canInvite, moderationState = roomModerationState, + selectedSection = selectedSection, eventSink = ::handleEvent, ) } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt index 404ecb523e..498dfd0180 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt @@ -21,10 +21,16 @@ data class RoomMemberListState( val searchResults: SearchBarResultState>, val isSearchActive: Boolean, val canInvite: Boolean, + val selectedSection: SelectedSection, val moderationState: RoomMemberModerationState, val eventSink: (RoomMemberListEvents) -> Unit, ) +enum class SelectedSection { + MEMBERS, + BANNED +} + data class RoomMembers( val invited: ImmutableList, val joined: ImmutableList, diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt index 2194019e70..312efef35c 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt @@ -21,107 +21,131 @@ import kotlinx.collections.immutable.persistentListOf internal class RoomMemberListStateProvider : PreviewParameterProvider { override val values: Sequence - get() = sequenceOf( - aRoomMemberListState( - roomMembers = AsyncData.Success( - RoomMembers( - invited = persistentListOf(aVictor().withIdentity(), aWalter().withIdentity()), - joined = persistentListOf(anAlice().withIdentity(), aBob().withIdentity(), aWalter().withIdentity()), - banned = persistentListOf(), - ) - ) - ), - aRoomMemberListState( - roomMembers = AsyncData.Success( - RoomMembers( - invited = persistentListOf(aVictor().withIdentity(), aWalter().withIdentity()), - joined = persistentListOf( - anAlice().withIdentity(identityState = IdentityState.Verified), - aBob().withIdentity(identityState = IdentityState.PinViolation), - aWalter().withIdentity(identityState = IdentityState.VerificationViolation) - ), - banned = persistentListOf(), - ) - ), - moderationState = aRoomMemberModerationState(canBan = true) - ), - aRoomMemberListState(roomMembers = AsyncData.Loading()), - aRoomMemberListState().copy(canInvite = true), - aRoomMemberListState().copy(isSearchActive = false), - aRoomMemberListState().copy(isSearchActive = true), - aRoomMemberListState().copy(isSearchActive = true, searchQuery = "someone"), - aRoomMemberListState().copy( - isSearchActive = true, - searchQuery = "@someone:matrix.org", - searchResults = SearchBarResultState.Results( - AsyncData.Success( - RoomMembers( - invited = persistentListOf(aVictor().withIdentity()), - joined = persistentListOf(anAlice().withIdentity()), - banned = persistentListOf(), - ) - ) - ), - ), - aRoomMemberListState().copy( - isSearchActive = true, - searchQuery = "something-with-no-results", - searchResults = SearchBarResultState.NoResultsFound() - ), - aRoomMemberListState( - roomMembers = AsyncData.Failure(Exception("Error details")), - ), - ) + get() = roomMemberListStates() + bannedRoomMemberListStates() } -internal class RoomMemberListStateBannedProvider : PreviewParameterProvider { - override val values: Sequence - get() = sequenceOf( - aRoomMemberListState( - roomMembers = AsyncData.Success( - RoomMembers( - invited = persistentListOf(), - joined = persistentListOf(), - banned = persistentListOf( - aRoomMember(userId = UserId("@alice:example.com"), displayName = "Alice").withIdentity(), - aRoomMember(userId = UserId("@bob:example.com"), displayName = "Bob").withIdentity(), - aRoomMember(userId = UserId("@charlie:example.com"), displayName = "Charlie").withIdentity(), - ), - ) - ), - moderationState = aRoomMemberModerationState(), +private fun roomMemberListStates(): Sequence = sequenceOf( + aRoomMemberListState( + roomMembers = AsyncData.Success( + RoomMembers( + invited = persistentListOf(aVictor().withIdentity(), aWalter().withIdentity()), + joined = persistentListOf(anAlice().withIdentity(), aBob().withIdentity(), aWalter().withIdentity()), + banned = persistentListOf(), ), - aRoomMemberListState( - roomMembers = AsyncData.Loading( - RoomMembers( - invited = persistentListOf(), - joined = persistentListOf(), - banned = persistentListOf( - aRoomMember(userId = UserId("@alice:example.com"), displayName = "Alice").withIdentity(), - aRoomMember(userId = UserId("@bob:example.com"), displayName = "Bob").withIdentity(), - aRoomMember(userId = UserId("@charlie:example.com"), displayName = "Charlie").withIdentity(), - ), - ) + ), + selectedSection = SelectedSection.MEMBERS, + ), + aRoomMemberListState( + roomMembers = AsyncData.Success( + RoomMembers( + invited = persistentListOf(aVictor().withIdentity(), aWalter().withIdentity()), + joined = persistentListOf( + anAlice().withIdentity(identityState = IdentityState.Verified), + aBob().withIdentity(identityState = IdentityState.PinViolation), + aWalter().withIdentity(identityState = IdentityState.VerificationViolation) ), - moderationState = aRoomMemberModerationState(), - ), - aRoomMemberListState( - roomMembers = AsyncData.Success( - RoomMembers( - invited = persistentListOf(), - joined = persistentListOf(), - banned = persistentListOf(), - ) - ), - moderationState = aRoomMemberModerationState(), + banned = persistentListOf(), ) - ) -} + ), + selectedSection = SelectedSection.MEMBERS, + moderationState = aRoomMemberModerationState(canBan = true) + ), + aRoomMemberListState( + roomMembers = AsyncData.Loading(), + selectedSection = SelectedSection.MEMBERS, + ), + aRoomMemberListState().copy( + canInvite = true, + selectedSection = SelectedSection.MEMBERS, + ), + aRoomMemberListState().copy( + isSearchActive = false, + selectedSection = SelectedSection.MEMBERS, + ), + aRoomMemberListState().copy( + isSearchActive = true, + selectedSection = SelectedSection.MEMBERS, + ), + aRoomMemberListState().copy( + isSearchActive = true, + searchQuery = "someone", + selectedSection = SelectedSection.MEMBERS, + ), + aRoomMemberListState().copy( + isSearchActive = true, + searchQuery = "@someone:matrix.org", + searchResults = SearchBarResultState.Results( + AsyncData.Success( + RoomMembers( + invited = persistentListOf(aVictor().withIdentity()), + joined = persistentListOf(anAlice().withIdentity()), + banned = persistentListOf(), + ) + ) + ), + selectedSection = SelectedSection.MEMBERS, + ), + aRoomMemberListState().copy( + isSearchActive = true, + searchQuery = "something-with-no-results", + searchResults = SearchBarResultState.NoResultsFound(), + selectedSection = SelectedSection.MEMBERS, + ), + aRoomMemberListState( + roomMembers = AsyncData.Failure(Exception("Error details")), + selectedSection = SelectedSection.MEMBERS, + ), +) + +private fun bannedRoomMemberListStates(): Sequence = sequenceOf( + aRoomMemberListState( + roomMembers = AsyncData.Success( + RoomMembers( + invited = persistentListOf(), + joined = persistentListOf(), + banned = persistentListOf( + aRoomMember(userId = UserId("@alice:example.com"), displayName = "Alice").withIdentity(), + aRoomMember(userId = UserId("@bob:example.com"), displayName = "Bob").withIdentity(), + aRoomMember(userId = UserId("@charlie:example.com"), displayName = "Charlie").withIdentity(), + ), + ) + ), + moderationState = aRoomMemberModerationState(), + selectedSection = SelectedSection.BANNED, + ), + aRoomMemberListState( + roomMembers = AsyncData.Loading( + RoomMembers( + invited = persistentListOf(), + joined = persistentListOf(), + banned = persistentListOf( + aRoomMember(userId = UserId("@alice:example.com"), displayName = "Alice").withIdentity(), + aRoomMember(userId = UserId("@bob:example.com"), displayName = "Bob").withIdentity(), + aRoomMember(userId = UserId("@charlie:example.com"), displayName = "Charlie").withIdentity(), + ), + ) + ), + moderationState = aRoomMemberModerationState(), + selectedSection = SelectedSection.BANNED, + ), + aRoomMemberListState( + roomMembers = AsyncData.Success( + RoomMembers( + invited = persistentListOf(), + joined = persistentListOf(), + banned = persistentListOf(), + ) + ), + moderationState = aRoomMemberModerationState(), + selectedSection = SelectedSection.BANNED, + ) +) internal fun aRoomMemberListState( roomMembers: AsyncData = AsyncData.Loading(), searchResults: SearchBarResultState> = SearchBarResultState.Initial(), moderationState: RoomMemberModerationState = aRoomMemberModerationState(), + selectedSection: SelectedSection = SelectedSection.MEMBERS, ) = RoomMemberListState( roomMembers = roomMembers, searchQuery = "", @@ -129,6 +153,7 @@ internal fun aRoomMemberListState( isSearchActive = false, canInvite = false, moderationState = moderationState, + selectedSection = SelectedSection.MEMBERS, eventSink = {} ) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt index 2b1ebb175c..b2a51aa446 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt @@ -30,10 +30,7 @@ import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.material3.SingleChoiceSegmentedButtonRow import androidx.compose.runtime.Composable -import androidx.compose.runtime.SideEffect import androidx.compose.runtime.getValue -import androidx.compose.runtime.mutableStateOf -import androidx.compose.runtime.remember import androidx.compose.runtime.setValue import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier @@ -48,6 +45,7 @@ import io.element.android.features.roomdetails.impl.R import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.button.BackButton +import io.element.android.libraries.designsystem.components.form.textFieldState import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Icon @@ -68,17 +66,11 @@ import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf -private enum class SelectedSection { - MEMBERS, - BANNED -} - @Composable fun RoomMemberListView( state: RoomMemberListState, navigator: RoomMemberListNavigator, modifier: Modifier = Modifier, - initialSelectedSectionIndex: Int = 0, ) { fun onSelectUser(roomMember: RoomMember) { state.eventSink(RoomMemberListEvents.RoomMemberSelected(roomMember)) @@ -96,12 +88,6 @@ fun RoomMemberListView( } } ) { padding -> - var selectedSection by remember { mutableStateOf(SelectedSection.entries[initialSelectedSectionIndex]) } - if (!state.moderationState.canBan && selectedSection == SelectedSection.BANNED) { - SideEffect { - selectedSection = SelectedSection.MEMBERS - } - } Column( modifier = Modifier .fillMaxWidth() @@ -117,7 +103,7 @@ fun RoomMemberListView( onActiveChange = { state.eventSink(RoomMemberListEvents.OnSearchActiveChanged(it)) }, onTextChange = { state.eventSink(RoomMemberListEvents.UpdateSearchQuery(it)) }, onSelectUser = ::onSelectUser, - selectedSection = selectedSection, + selectedSection = state.selectedSection, modifier = Modifier.fillMaxWidth(), ) @@ -126,8 +112,8 @@ fun RoomMemberListView( roomMembers = state.roomMembers, showMembersCount = true, canDisplayBannedUsersControls = state.moderationState.canBan, - selectedSection = selectedSection, - onSelectedSectionChange = { selectedSection = it }, + selectedSection = state.selectedSection, + onSelectedSectionChange = { state.eventSink(RoomMemberListEvents.ChangeSelectedSection(it)) }, onSelectUser = ::onSelectUser, ) } @@ -380,9 +366,13 @@ private fun RoomMemberSearchBar( selectedSection: SelectedSection, modifier: Modifier = Modifier, ) { + var queryFieldState by textFieldState(query) SearchBar( - query = query, - onQueryChange = onTextChange, + query = queryFieldState, + onQueryChange = { newQuery -> + queryFieldState = newQuery + onTextChange(newQuery) + }, active = active, onActiveChange = onActiveChange, modifier = modifier, @@ -409,13 +399,3 @@ internal fun RoomMemberListViewPreview(@PreviewParameter(RoomMemberListStateProv navigator = object : RoomMemberListNavigator {}, ) } - -@PreviewsDayNight -@Composable -internal fun RoomMemberListViewBannedPreview(@PreviewParameter(RoomMemberListStateBannedProvider::class) state: RoomMemberListState) = ElementPreview { - RoomMemberListView( - initialSelectedSectionIndex = 1, - state = state, - navigator = object : RoomMemberListNavigator {}, - ) -} From c765084f0008ff85d58a480e1f19e2877d13bb0d Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 20 Nov 2025 18:27:23 +0100 Subject: [PATCH 033/113] change(members): search is now dependent of the selected section --- .../impl/members/RoomMemberListDataSource.kt | 18 +++++++++++++----- .../impl/members/RoomMemberListPresenter.kt | 2 +- 2 files changed, 14 insertions(+), 6 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListDataSource.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListDataSource.kt index 87ae53c93c..5e00ce0937 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListDataSource.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListDataSource.kt @@ -13,23 +13,31 @@ import io.element.android.libraries.core.bool.orFalse import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.RoomMember +import io.element.android.libraries.matrix.api.room.RoomMembershipState import io.element.android.libraries.matrix.api.room.roomMembers import kotlinx.coroutines.withContext +import kotlin.collections.filter @Inject class RoomMemberListDataSource( private val room: BaseRoom, private val coroutineDispatchers: CoroutineDispatchers, ) { - suspend fun search(query: String): List = withContext(coroutineDispatchers.io) { + suspend fun search(query: String, selectedSection: SelectedSection): List = withContext(coroutineDispatchers.io) { val roomMembersState = room.membersStateFlow.value - val activeRoomMembers = roomMembersState.roomMembers() - ?.filter { it.membership.isActive() } + val displayableMembers = roomMembersState.roomMembers() .orEmpty() + .filter { + when(selectedSection){ + SelectedSection.MEMBERS -> it.membership.isActive() + SelectedSection.BANNED -> it.membership == RoomMembershipState.BAN + } + } + val filteredMembers = if (query.isBlank()) { - activeRoomMembers + displayableMembers } else { - activeRoomMembers.filter { member -> + displayableMembers.filter { member -> member.userId.value.contains(query, ignoreCase = true) || member.displayName?.contains(query, ignoreCase = true).orFalse() } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt index 65385e5f08..400432d331 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt @@ -130,7 +130,7 @@ class RoomMemberListPresenter( searchResults = if (searchQuery.isEmpty() || !isSearchActive) { SearchBarResultState.Initial() } else { - val results = roomMemberListDataSource.search(searchQuery).groupBy { it.membership } + val results = roomMemberListDataSource.search(searchQuery, selectedSection).groupBy { it.membership } if (results.isEmpty()) { SearchBarResultState.NoResultsFound() } else { From 24c2edc16e52c3db91acade016b1d8281d972d1d Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 20 Nov 2025 20:21:02 +0100 Subject: [PATCH 034/113] change(members): update RoomMemberModerationView --- .../impl/RoomMemberModerationView.kt | 42 ++++++++++--------- .../components/avatar/AvatarSize.kt | 2 +- 2 files changed, 23 insertions(+), 21 deletions(-) diff --git a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationView.kt b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationView.kt index 1e7251b20b..ac6c5bc4cb 100644 --- a/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationView.kt +++ b/features/roommembermoderation/impl/src/main/kotlin/io/element/android/features/roommembermoderation/impl/RoomMemberModerationView.kt @@ -232,32 +232,34 @@ private fun RoomMemberActionsBottomSheet( avatarData = user.getAvatarData(size = AvatarSize.RoomListManageUser), avatarType = AvatarType.User, modifier = Modifier - .padding(bottom = 28.dp) - .align(Alignment.CenterHorizontally) + .padding(bottom = 24.dp) + .align(Alignment.CenterHorizontally) ) - user.displayName?.let { - Text( - text = it, - style = ElementTheme.typography.fontHeadingLgBold, - maxLines = 1, - overflow = TextOverflow.Ellipsis, - textAlign = TextAlign.Center, - modifier = Modifier - .padding(start = 16.dp, end = 16.dp, bottom = 8.dp) - .fillMaxWidth() - ) - } + val bestName = user.getBestName() Text( - text = user.userId.value, - style = ElementTheme.typography.fontBodyLgRegular, - color = ElementTheme.colors.textSecondary, + text = bestName, + style = ElementTheme.typography.fontHeadingLgBold, maxLines = 1, overflow = TextOverflow.Ellipsis, textAlign = TextAlign.Center, modifier = Modifier + .padding(start = 16.dp, end = 16.dp, bottom = 8.dp) + .fillMaxWidth() + ) + // Show user ID only if it's different from the display name + if (bestName != user.userId.value) { + Text( + text = user.userId.value, + style = ElementTheme.typography.fontBodyMdRegular, + color = ElementTheme.colors.textSecondary, + maxLines = 1, + overflow = TextOverflow.Ellipsis, + textAlign = TextAlign.Center, + modifier = Modifier .padding(horizontal = 16.dp) .fillMaxWidth() - ) + ) + } Spacer(modifier = Modifier.height(32.dp)) for (actionState in actions) { @@ -330,8 +332,8 @@ internal fun RoomMemberModerationViewPreview(@PreviewParameter(InternalRoomMembe ElementPreview { Box( modifier = Modifier - .fillMaxWidth() - .heightIn(min = 64.dp) + .fillMaxWidth() + .heightIn(min = 64.dp) ) { RoomMemberModerationView( state = state, diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt index 31294c378f..0f99349494 100644 --- a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/components/avatar/AvatarSize.kt @@ -47,7 +47,7 @@ enum class AvatarSize(val dp: Dp) { InviteSender(16.dp), EditRoomDetails(70.dp), - RoomListManageUser(70.dp), + RoomListManageUser(96.dp), NotificationsOptIn(32.dp), From 3e125b465d80afbabe66209c6f5007cdefb88a5e Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 20 Nov 2025 21:54:01 +0100 Subject: [PATCH 035/113] design: introduce SearchField component --- .../theme/components/SearchField.kt | 224 ++++++++++++++++++ 1 file changed, 224 insertions(+) create mode 100644 libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchField.kt diff --git a/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchField.kt b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchField.kt new file mode 100644 index 0000000000..fc84abe827 --- /dev/null +++ b/libraries/designsystem/src/main/kotlin/io/element/android/libraries/designsystem/theme/components/SearchField.kt @@ -0,0 +1,224 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2023-2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.designsystem.theme.components + +import androidx.compose.foundation.BorderStroke +import androidx.compose.foundation.background +import androidx.compose.foundation.interaction.MutableInteractionSource +import androidx.compose.foundation.interaction.collectIsFocusedAsState +import androidx.compose.foundation.layout.Arrangement.spacedBy +import androidx.compose.foundation.layout.Box +import androidx.compose.foundation.layout.Column +import androidx.compose.foundation.layout.Row +import androidx.compose.foundation.layout.Spacer +import androidx.compose.foundation.layout.padding +import androidx.compose.foundation.layout.width +import androidx.compose.foundation.shape.CircleShape +import androidx.compose.foundation.shape.RoundedCornerShape +import androidx.compose.foundation.text.BasicTextField +import androidx.compose.foundation.text.KeyboardActions +import androidx.compose.foundation.text.KeyboardOptions +import androidx.compose.runtime.Composable +import androidx.compose.runtime.getValue +import androidx.compose.runtime.remember +import androidx.compose.ui.Alignment +import androidx.compose.ui.Modifier +import androidx.compose.ui.graphics.SolidColor +import androidx.compose.ui.platform.LocalFocusManager +import androidx.compose.ui.res.stringResource +import androidx.compose.ui.text.TextStyle +import androidx.compose.ui.text.input.ImeAction +import androidx.compose.ui.text.input.TextFieldValue +import androidx.compose.ui.tooling.preview.Preview +import androidx.compose.ui.unit.dp +import io.element.android.compound.theme.ElementTheme +import io.element.android.compound.tokens.generated.CompoundIcons +import io.element.android.libraries.architecture.coverage.ExcludeFromCoverage +import io.element.android.libraries.designsystem.preview.ElementPreviewDark +import io.element.android.libraries.designsystem.preview.ElementPreviewLight +import io.element.android.libraries.designsystem.preview.PreviewGroup +import io.element.android.libraries.ui.strings.CommonStrings + +/** + * https://www.figma.com/design/G1xy0HDZKJf5TCRFmKb5d5/Compound-Android-Components?node-id=1985-3223 + */ +@Composable +fun SearchField( + value: String, + onValueChange: (String) -> Unit, + modifier: Modifier = Modifier, + placeholder: String? = null, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, +) { + val focusManager = LocalFocusManager.current + val isFocused by interactionSource.collectIsFocusedAsState() + BasicTextField( + value = value, + onValueChange = onValueChange, + modifier = modifier, + textStyle = textFieldStyle(), + singleLine = true, + interactionSource = interactionSource, + keyboardOptions = KeyboardOptions( + imeAction = ImeAction.Search, + ), + keyboardActions = KeyboardActions( + onSearch = { + focusManager.clearFocus() + } + ), + cursorBrush = SolidColor(ElementTheme.colors.textActionAccent), + ) { innerTextField -> + DecorationBox( + isFocused = isFocused, + placeholder = placeholder, + isTextEmpty = value.isEmpty(), + innerTextField = innerTextField, + onClear = { onValueChange("") }, + ) + } +} + +@Composable +fun SearchField( + value: TextFieldValue, + onValueChange: (TextFieldValue) -> Unit, + modifier: Modifier = Modifier, + placeholder: String? = null, + interactionSource: MutableInteractionSource = remember { MutableInteractionSource() }, +) { + val focusManager = LocalFocusManager.current + val isFocused by interactionSource.collectIsFocusedAsState() + BasicTextField( + value = value, + onValueChange = onValueChange, + modifier = modifier, + textStyle = textFieldStyle(), + singleLine = true, + interactionSource = interactionSource, + keyboardOptions = KeyboardOptions( + imeAction = ImeAction.Search, + ), + keyboardActions = KeyboardActions( + onSearch = { + focusManager.clearFocus() + } + ), + cursorBrush = SolidColor(ElementTheme.colors.textActionAccent), + ) { innerTextField -> + DecorationBox( + isFocused = isFocused, + placeholder = placeholder, + isTextEmpty = value.text.isEmpty(), + innerTextField = innerTextField, + onClear = { TextFieldValue() } + ) + } +} + +@Composable +private fun DecorationBox( + isFocused: Boolean, + placeholder: String?, + isTextEmpty: Boolean, + onClear: () -> Unit, + innerTextField: @Composable () -> Unit, +) { + SearchFieldContainer( + isFocused = isFocused, + ) { + Row(modifier = Modifier.padding(start = 16.dp), verticalAlignment = Alignment.CenterVertically) { + Box(modifier = Modifier.weight(1f)) { + if (placeholder != null && isTextEmpty) { + Text( + text = placeholder, + color = ElementTheme.colors.textSecondary, + style = ElementTheme.typography.fontBodyLgRegular, + ) + } + innerTextField() + } + Spacer(modifier = Modifier.width(16.dp)) + val showClearIcon = isFocused && !isTextEmpty + IconButton(onClick = onClear, enabled = showClearIcon) { + if (showClearIcon) { + Icon( + modifier = Modifier.background(ElementTheme.colors.iconSecondary, CircleShape), + imageVector = CompoundIcons.Close(), + contentDescription = stringResource(CommonStrings.action_clear), + tint = ElementTheme.colors.iconOnSolidPrimary, + ) + } else { + Icon( + imageVector = CompoundIcons.Search(), + contentDescription = null, + tint = ElementTheme.colors.iconTertiary, + ) + } + } + } + } +} + +@Composable +private fun SearchFieldContainer( + isFocused: Boolean, + modifier: Modifier = Modifier, + content: @Composable () -> Unit +) { + Surface( + modifier = modifier, + shape = RoundedCornerShape(99.dp), + border = BorderStroke( + width = 1.dp, + color = if (isFocused) { + ElementTheme.colors.borderInteractiveHovered + } else { + ElementTheme.colors.borderInteractiveSecondary + } + ), + color = ElementTheme.colors.bgSubtleSecondary, + content = content + ) +} + +@Composable +private fun textFieldStyle(): TextStyle { + return ElementTheme.typography.fontBodyLgRegular.copy( + color = ElementTheme.colors.textPrimary + ) +} + +@Preview(group = PreviewGroup.Search, heightDp = 1000) +@Composable +internal fun SearchFieldsLightPreview() = ElementPreviewLight { ContentToPreview() } + +@Preview(group = PreviewGroup.Search, heightDp = 1000) +@Composable +internal fun SearchFieldsDarkPreview() = ElementPreviewDark { ContentToPreview() } + +@Composable +@ExcludeFromCoverage +private fun ContentToPreview() { + Column( + modifier = Modifier.padding(8.dp), + verticalArrangement = spacedBy(8.dp) + ) { + SearchField( + onValueChange = {}, + placeholder = "Search", + value = "", + ) + SearchField( + onValueChange = {}, + placeholder = "Search", + value = "Search term", + ) + } +} From 0beeda6001f615b3e9a09d68f46023886d598736 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 21 Nov 2025 11:53:03 +0100 Subject: [PATCH 036/113] misc: AsyncData map non nullable --- .../features/space/impl/leave/LeaveSpacePresenter.kt | 2 +- .../io/element/android/libraries/architecture/AsyncData.kt | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenter.kt b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenter.kt index 1d5e614113..a331aefccd 100644 --- a/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenter.kt +++ b/features/space/impl/src/main/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenter.kt @@ -88,7 +88,7 @@ class LeaveSpacePresenter( } LaunchedEffect(selectedRoomIds, leaveSpaceRooms) { selectableSpaceRooms = leaveSpaceRooms.map { - it?.others.orEmpty().map { room -> + it.others.map { room -> SelectableSpaceRoom( spaceRoom = room.spaceRoom, isLastAdmin = room.isLastAdmin, diff --git a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncData.kt b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncData.kt index 5dcf1f933a..118addf1fe 100644 --- a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncData.kt +++ b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncData.kt @@ -163,14 +163,14 @@ suspend inline fun runUpdatingState( } inline fun AsyncData.map( - transform: (T?) -> R, + transform: (T) -> R, ): AsyncData { return when (this) { is AsyncData.Failure -> AsyncData.Failure( error = error, - prevData = transform(prevData) + prevData = prevData?.let { transform(prevData) } ) - is AsyncData.Loading -> AsyncData.Loading(transform(prevData)) + is AsyncData.Loading -> AsyncData.Loading(prevData?.let { transform(prevData) }) is AsyncData.Success -> AsyncData.Success(transform(data)) AsyncData.Uninitialized -> AsyncData.Uninitialized } From a3bb1b93abb3e87e1715d52953c2a4ccc61f4db6 Mon Sep 17 00:00:00 2001 From: ganfra Date: Fri, 21 Nov 2025 11:54:07 +0100 Subject: [PATCH 037/113] change(members): use SearchField and update strings --- .../impl/src/main/res/values/localazy.xml | 6 +- .../impl/members/RoomMemberListDataSource.kt | 47 ----- .../impl/members/RoomMemberListEvents.kt | 1 - .../impl/members/RoomMemberListPresenter.kt | 50 +---- .../impl/members/RoomMemberListState.kt | 22 ++- .../members/RoomMemberListStateProvider.kt | 20 +- .../impl/members/RoomMemberListView.kt | 184 +++++++----------- .../impl/src/main/res/values/localazy.xml | 8 +- tools/localazy/config.json | 1 + 9 files changed, 113 insertions(+), 226 deletions(-) delete mode 100644 features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListDataSource.kt diff --git a/features/rolesandpermissions/impl/src/main/res/values/localazy.xml b/features/rolesandpermissions/impl/src/main/res/values/localazy.xml index 2d98f43f97..77ab04749f 100644 --- a/features/rolesandpermissions/impl/src/main/res/values/localazy.xml +++ b/features/rolesandpermissions/impl/src/main/res/values/localazy.xml @@ -35,8 +35,8 @@ "Save changes?" "There are no banned users." - "%1$d person" - "%1$d people" + "%1$d Person" + "%1$d People" "Ban user" "Only remove member" @@ -45,7 +45,7 @@ "Unban user" "Banned" "Members" - "Pending" + "%1$d Invited" "Admin" "Moderator" "Owner" diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListDataSource.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListDataSource.kt deleted file mode 100644 index 5e00ce0937..0000000000 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListDataSource.kt +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-2025 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.features.roomdetails.impl.members - -import dev.zacsweers.metro.Inject -import io.element.android.libraries.core.bool.orFalse -import io.element.android.libraries.core.coroutine.CoroutineDispatchers -import io.element.android.libraries.matrix.api.room.BaseRoom -import io.element.android.libraries.matrix.api.room.RoomMember -import io.element.android.libraries.matrix.api.room.RoomMembershipState -import io.element.android.libraries.matrix.api.room.roomMembers -import kotlinx.coroutines.withContext -import kotlin.collections.filter - -@Inject -class RoomMemberListDataSource( - private val room: BaseRoom, - private val coroutineDispatchers: CoroutineDispatchers, -) { - suspend fun search(query: String, selectedSection: SelectedSection): List = withContext(coroutineDispatchers.io) { - val roomMembersState = room.membersStateFlow.value - val displayableMembers = roomMembersState.roomMembers() - .orEmpty() - .filter { - when(selectedSection){ - SelectedSection.MEMBERS -> it.membership.isActive() - SelectedSection.BANNED -> it.membership == RoomMembershipState.BAN - } - } - - val filteredMembers = if (query.isBlank()) { - displayableMembers - } else { - displayableMembers.filter { member -> - member.userId.value.contains(query, ignoreCase = true) || - member.displayName?.contains(query, ignoreCase = true).orFalse() - } - } - filteredMembers - } -} diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt index 9a8798124e..a4b7b22bf3 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt @@ -13,6 +13,5 @@ import io.element.android.libraries.matrix.api.room.RoomMember sealed interface RoomMemberListEvents { data class ChangeSelectedSection(val section: SelectedSection): RoomMemberListEvents data class UpdateSearchQuery(val query: String) : RoomMemberListEvents - data class OnSearchActiveChanged(val active: Boolean) : RoomMemberListEvents data class RoomMemberSelected(val roomMember: RoomMember) : RoomMemberListEvents } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt index 400432d331..44e0aa168f 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt @@ -23,6 +23,7 @@ import io.element.android.features.roommembermoderation.api.RoomMemberModeration import io.element.android.features.roommembermoderation.api.RoomMemberModerationState import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter +import io.element.android.libraries.architecture.map import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.core.UserId @@ -41,7 +42,6 @@ import kotlinx.collections.immutable.ImmutableMap import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableMap -import kotlinx.coroutines.flow.first import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.withContext @@ -63,8 +63,6 @@ class RoomMemberListPresenter( var searchResults by remember { mutableStateOf>>(SearchBarResultState.Initial()) } - var isSearchActive by rememberSaveable { mutableStateOf(false) } - val membersState by room.membersStateFlow.collectAsState() val syncUpdateFlow = room.syncUpdateFlow.collectAsState() val canInvite by room.canInviteAsState(syncUpdateFlow.value) @@ -78,8 +76,9 @@ class RoomMemberListPresenter( .launchIn(this) } - var roomMembers: AsyncData by remember { mutableStateOf(AsyncData.Loading())} - var selectedSection by remember { mutableStateOf(SelectedSection.MEMBERS)} + var roomMembers: AsyncData by remember { mutableStateOf(AsyncData.Loading()) } + var selectedSection by remember { mutableStateOf(SelectedSection.MEMBERS) } + var filteredRoomMembers: AsyncData by remember { mutableStateOf(AsyncData.Loading()) } // Update the room members when the screen is loaded LaunchedEffect(Unit) { @@ -98,7 +97,7 @@ class RoomMemberListPresenter( } withContext(coroutineDispatchers.io) { val members = membersState.roomMembers().orEmpty().groupBy { it.membership } - val info = room.roomInfoFlow.first() + val info = room.info() if (members.getOrDefault(RoomMembershipState.JOIN, emptyList()).size < info.joinedMembersCount / 2) { // Don't display initial room member list if we have less than half of the joined members: // This result will come from the timeline loading membership events and it'll be wrong. @@ -125,43 +124,16 @@ class RoomMemberListPresenter( } } - LaunchedEffect(membersState, searchQuery, isSearchActive) { - withContext(coroutineDispatchers.io) { - searchResults = if (searchQuery.isEmpty() || !isSearchActive) { - SearchBarResultState.Initial() - } else { - val results = roomMemberListDataSource.search(searchQuery, selectedSection).groupBy { it.membership } - if (results.isEmpty()) { - SearchBarResultState.NoResultsFound() - } else { - val result = RoomMembers( - invited = results.getOrDefault(RoomMembershipState.INVITE, emptyList()) - .map { it.withIdentityState(roomMemberIdentityStates) } - .toImmutableList(), - joined = results.getOrDefault(RoomMembershipState.JOIN, emptyList()) - .sortedWith(powerLevelRoomMemberComparator) - .map { it.withIdentityState(roomMemberIdentityStates) } - .toImmutableList(), - banned = results.getOrDefault(RoomMembershipState.BAN, emptyList()) - .sortedBy { it.userId.value } - .map { it.withIdentityState(roomMemberIdentityStates) } - .toImmutableList(), - ) - SearchBarResultState.Results( - if (membersState is RoomMembersState.Pending) { - AsyncData.Loading(result) - } else { - AsyncData.Success(result) - } - ) - } + LaunchedEffect(searchQuery, roomMembers) { + filteredRoomMembers = roomMembers.map { members -> + withContext(coroutineDispatchers.io) { + members.filter(searchQuery) } } } fun handleEvent(event: RoomMemberListEvents) { when (event) { - is RoomMemberListEvents.OnSearchActiveChanged -> isSearchActive = event.active is RoomMemberListEvents.UpdateSearchQuery -> searchQuery = event.query is RoomMemberListEvents.RoomMemberSelected -> roomModerationState.eventSink(ShowActionsForUser(event.roomMember.toMatrixUser())) @@ -176,10 +148,8 @@ class RoomMemberListPresenter( } return RoomMemberListState( - roomMembers = roomMembers, + roomMembers = filteredRoomMembers, searchQuery = searchQuery, - searchResults = searchResults, - isSearchActive = isSearchActive, canInvite = canInvite, moderationState = roomModerationState, selectedSection = selectedSection, diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt index 498dfd0180..b59f67a915 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt @@ -10,16 +10,15 @@ package io.element.android.features.roomdetails.impl.members import io.element.android.features.roommembermoderation.api.RoomMemberModerationState import io.element.android.libraries.architecture.AsyncData -import io.element.android.libraries.designsystem.theme.components.SearchBarResultState +import io.element.android.libraries.core.bool.orFalse import io.element.android.libraries.matrix.api.encryption.identity.IdentityState import io.element.android.libraries.matrix.api.room.RoomMember import kotlinx.collections.immutable.ImmutableList +import kotlinx.collections.immutable.toImmutableList data class RoomMemberListState( val roomMembers: AsyncData, val searchQuery: String, - val searchResults: SearchBarResultState>, - val isSearchActive: Boolean, val canInvite: Boolean, val selectedSection: SelectedSection, val moderationState: RoomMemberModerationState, @@ -35,7 +34,22 @@ data class RoomMembers( val invited: ImmutableList, val joined: ImmutableList, val banned: ImmutableList, -) +){ + fun filter(query: String): RoomMembers { + if (query.isBlank()) { + return this + } + val filterPredicate = { member: RoomMemberWithIdentityState -> + member.roomMember.userId.value.contains(query, ignoreCase = true) || + member.roomMember.displayName?.contains(query, ignoreCase = true).orFalse() + } + return RoomMembers( + invited = invited.filter(filterPredicate).toImmutableList(), + joined = joined.filter(filterPredicate).toImmutableList(), + banned = banned.filter(filterPredicate).toImmutableList(), + ) + } +} data class RoomMemberWithIdentityState( val roomMember: RoomMember, diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt index 312efef35c..dafe2546d5 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt @@ -59,36 +59,21 @@ private fun roomMemberListStates(): Sequence = sequenceOf( selectedSection = SelectedSection.MEMBERS, ), aRoomMemberListState().copy( - isSearchActive = false, selectedSection = SelectedSection.MEMBERS, ), aRoomMemberListState().copy( - isSearchActive = true, selectedSection = SelectedSection.MEMBERS, ), aRoomMemberListState().copy( - isSearchActive = true, searchQuery = "someone", selectedSection = SelectedSection.MEMBERS, ), aRoomMemberListState().copy( - isSearchActive = true, searchQuery = "@someone:matrix.org", - searchResults = SearchBarResultState.Results( - AsyncData.Success( - RoomMembers( - invited = persistentListOf(aVictor().withIdentity()), - joined = persistentListOf(anAlice().withIdentity()), - banned = persistentListOf(), - ) - ) - ), selectedSection = SelectedSection.MEMBERS, ), aRoomMemberListState().copy( - isSearchActive = true, searchQuery = "something-with-no-results", - searchResults = SearchBarResultState.NoResultsFound(), selectedSection = SelectedSection.MEMBERS, ), aRoomMemberListState( @@ -143,17 +128,14 @@ private fun bannedRoomMemberListStates(): Sequence = sequen internal fun aRoomMemberListState( roomMembers: AsyncData = AsyncData.Loading(), - searchResults: SearchBarResultState> = SearchBarResultState.Initial(), moderationState: RoomMemberModerationState = aRoomMemberModerationState(), selectedSection: SelectedSection = SelectedSection.MEMBERS, ) = RoomMemberListState( roomMembers = roomMembers, searchQuery = "", - searchResults = searchResults, - isSearchActive = false, canInvite = false, moderationState = moderationState, - selectedSection = SelectedSection.MEMBERS, + selectedSection = selectedSection, eventSink = {} ) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt index b2a51aa446..74d3305ff5 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt @@ -51,8 +51,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.LinearProgressIndicator import io.element.android.libraries.designsystem.theme.components.Scaffold -import io.element.android.libraries.designsystem.theme.components.SearchBar -import io.element.android.libraries.designsystem.theme.components.SearchBarResultState +import io.element.android.libraries.designsystem.theme.components.SearchField import io.element.android.libraries.designsystem.theme.components.SegmentedButton import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.designsystem.theme.components.TextButton @@ -79,44 +78,39 @@ fun RoomMemberListView( Scaffold( modifier = modifier, topBar = { - if (!state.isSearchActive) { - RoomMemberListTopBar( - canInvite = state.canInvite, - onBackClick = navigator::exitRoomMemberList, - onInviteClick = navigator::openInviteMembers, - ) - } + RoomMemberListTopBar( + canInvite = state.canInvite, + onBackClick = navigator::exitRoomMemberList, + onInviteClick = navigator::openInviteMembers, + ) } ) { padding -> Column( modifier = Modifier - .fillMaxWidth() - .padding(padding) - .consumeWindowInsets(padding), + .fillMaxWidth() + .padding(padding) + .consumeWindowInsets(padding), verticalArrangement = Arrangement.spacedBy(16.dp), ) { - RoomMemberSearchBar( - query = state.searchQuery, - state = state.searchResults, - active = state.isSearchActive, - placeHolderTitle = stringResource(CommonStrings.common_search_for_someone), - onActiveChange = { state.eventSink(RoomMemberListEvents.OnSearchActiveChanged(it)) }, - onTextChange = { state.eventSink(RoomMemberListEvents.UpdateSearchQuery(it)) }, - onSelectUser = ::onSelectUser, - selectedSection = state.selectedSection, - modifier = Modifier.fillMaxWidth(), + var searchQuery by textFieldState(state.searchQuery) + SearchField( + value = searchQuery, + onValueChange = { newQuery -> + searchQuery = newQuery + state.eventSink(RoomMemberListEvents.UpdateSearchQuery(newQuery)) + }, + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp), + placeholder = stringResource(CommonStrings.common_search_for_someone), + ) + RoomMemberList( + roomMembers = state.roomMembers, + selectedSection = state.selectedSection, + onSelectedSectionChange = { state.eventSink(RoomMemberListEvents.ChangeSelectedSection(it)) }, + showSections = state.moderationState.canBan, + onSelectUser = ::onSelectUser, ) - - if (!state.isSearchActive) { - RoomMemberList( - roomMembers = state.roomMembers, - showMembersCount = true, - canDisplayBannedUsersControls = state.moderationState.canBan, - selectedSection = state.selectedSection, - onSelectedSectionChange = { state.eventSink(RoomMemberListEvents.ChangeSelectedSection(it)) }, - onSelectUser = ::onSelectUser, - ) - } } } } @@ -124,25 +118,24 @@ fun RoomMemberListView( @Composable private fun RoomMemberList( roomMembers: AsyncData, - showMembersCount: Boolean, selectedSection: SelectedSection, + showSections: Boolean = true, onSelectedSectionChange: (SelectedSection) -> Unit, - canDisplayBannedUsersControls: Boolean, onSelectUser: (RoomMember) -> Unit, ) { LazyColumn(modifier = Modifier.fillMaxWidth(), state = rememberLazyListState()) { stickyHeader { Column { - if (canDisplayBannedUsersControls) { + if (showSections) { val segmentedButtonTitles = persistentListOf( stringResource(id = R.string.screen_room_member_list_mode_members), stringResource(id = R.string.screen_room_member_list_mode_banned), ) SingleChoiceSegmentedButtonRow( modifier = Modifier - .background(ElementTheme.colors.bgCanvasDefault) - .fillMaxWidth() - .padding(start = 16.dp, end = 16.dp, bottom = 16.dp), + .background(ElementTheme.colors.bgCanvasDefault) + .fillMaxWidth() + .padding(start = 16.dp, end = 16.dp, bottom = 16.dp), ) { for ((index, title) in segmentedButtonTitles.withIndex()) { SegmentedButton( @@ -171,7 +164,6 @@ private fun RoomMemberList( roomMembers = roomMembers.dataOrNull() ?: return@LazyColumn, selectedSection = selectedSection, onSelectUser = onSelectUser, - showMembersCount = showMembersCount, ) AsyncData.Uninitialized -> Unit } @@ -182,27 +174,29 @@ private fun LazyListScope.memberItems( roomMembers: RoomMembers, selectedSection: SelectedSection, onSelectUser: (RoomMember) -> Unit, - showMembersCount: Boolean, ) { when (selectedSection) { SelectedSection.MEMBERS -> { if (roomMembers.invited.isNotEmpty()) { - roomMemberListSection( - headerText = { stringResource(id = R.string.screen_room_member_list_pending_header_title) }, + roomMemberListSectionHeader( + text = { + val memberCount = roomMembers.invited.count() + stringResource(id = R.string.screen_room_member_list_pending_header_title, memberCount) + }, + ) + roomMemberListSectionItems( members = roomMembers.invited, onMemberSelected = { onSelectUser(it) } ) } if (roomMembers.joined.isNotEmpty()) { - roomMemberListSection( - headerText = { - if (showMembersCount) { - val memberCount = roomMembers.joined.count() - pluralStringResource(id = R.plurals.screen_room_member_list_header_title, count = memberCount, memberCount) - } else { - stringResource(id = R.string.screen_room_member_list_room_members_header_title) - } + roomMemberListSectionHeader( + text = { + val memberCount = roomMembers.joined.count() + pluralStringResource(id = R.plurals.screen_room_member_list_header_title, count = memberCount, memberCount) }, + ) + roomMemberListSectionItems( members = roomMembers.joined, onMemberSelected = { onSelectUser(it) } ) @@ -210,8 +204,14 @@ private fun LazyListScope.memberItems( } SelectedSection.BANNED -> { // Banned users if (roomMembers.banned.isNotEmpty()) { - roomMemberListSection( - headerText = null, + roomMemberListSectionHeader( + text = { + val memberCount = roomMembers.banned.count() + stringResource(id = R.string.screen_room_member_list_banned_header_title, memberCount) + }, + isCritical = true, + ) + roomMemberListSectionItems( members = roomMembers.banned, onMemberSelected = { onSelectUser(it) } ) @@ -219,13 +219,13 @@ private fun LazyListScope.memberItems( item { Box( Modifier - .fillParentMaxSize() - .padding(horizontal = 16.dp) + .fillParentMaxSize() + .padding(horizontal = 16.dp) ) { Text( modifier = Modifier - .padding(bottom = 56.dp) - .align(Alignment.Center), + .padding(bottom = 56.dp) + .align(Alignment.Center), text = stringResource(id = R.string.screen_room_member_list_banned_empty), color = ElementTheme.colors.textSecondary, textAlign = TextAlign.Center, @@ -241,8 +241,8 @@ private fun LazyListScope.failureItem(failure: Throwable) { item { Text( modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 32.dp), + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 32.dp), text = stringResource(id = CommonStrings.error_unknown) + "\n\n" + failure.localizedMessage, color = ElementTheme.colors.textCriticalPrimary, textAlign = TextAlign.Center, @@ -250,21 +250,25 @@ private fun LazyListScope.failureItem(failure: Throwable) { } } -private fun LazyListScope.roomMemberListSection( - headerText: @Composable (() -> String)?, +private fun LazyListScope.roomMemberListSectionHeader( + text: @Composable (() -> String), + modifier: Modifier = Modifier, + isCritical: Boolean = false, +) { + item { + Text( + modifier = modifier.padding(horizontal = 16.dp, vertical = 12.dp), + text = text(), + style = ElementTheme.typography.fontBodyLgMedium, + color = if (isCritical) ElementTheme.colors.textCriticalPrimary else ElementTheme.colors.textPrimary, + ) + } +} + +private fun LazyListScope.roomMemberListSectionItems( members: ImmutableList?, onMemberSelected: (RoomMember) -> Unit, ) { - headerText?.let { - item { - Text( - modifier = Modifier.padding(horizontal = 16.dp, vertical = 12.dp), - text = it(), - style = ElementTheme.typography.fontBodyLgRegular, - color = ElementTheme.colors.textSecondary, - ) - } - } items(members.orEmpty()) { matrixUser -> RoomMemberListItem( modifier = Modifier.fillMaxWidth(), @@ -353,44 +357,6 @@ private fun RoomMemberListTopBar( ) } -@OptIn(ExperimentalMaterial3Api::class) -@Composable -private fun RoomMemberSearchBar( - query: String, - state: SearchBarResultState>, - active: Boolean, - placeHolderTitle: String, - onActiveChange: (Boolean) -> Unit, - onTextChange: (String) -> Unit, - onSelectUser: (RoomMember) -> Unit, - selectedSection: SelectedSection, - modifier: Modifier = Modifier, -) { - var queryFieldState by textFieldState(query) - SearchBar( - query = queryFieldState, - onQueryChange = { newQuery -> - queryFieldState = newQuery - onTextChange(newQuery) - }, - active = active, - onActiveChange = onActiveChange, - modifier = modifier, - placeHolderTitle = placeHolderTitle, - resultState = state, - resultHandler = { results -> - RoomMemberList( - roomMembers = results, - showMembersCount = false, - onSelectUser = { onSelectUser(it) }, - canDisplayBannedUsersControls = false, - selectedSection = selectedSection, - onSelectedSectionChange = {}, - ) - }, - ) -} - @PreviewsDayNight @Composable internal fun RoomMemberListViewPreview(@PreviewParameter(RoomMemberListStateProvider::class) state: RoomMemberListState) = ElementPreview { diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index 2f9f2de9b7..4d8e634e81 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -71,9 +71,10 @@ "Topic" "Updating room…" "There are no banned users." + "%1$d Banned" - "%1$d person" - "%1$d people" + "%1$d Person" + "%1$d People" "Ban user" "Only remove member" @@ -82,7 +83,8 @@ "Unban user" "Banned" "Members" - "Pending" + "%1$d Invited" + "Pending" "Admin" "Moderator" "Owner" diff --git a/tools/localazy/config.json b/tools/localazy/config.json index 405451bb34..27ca1ecd12 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -198,6 +198,7 @@ "screen_room_details_.*", "screen\\.room_details\\..*", "screen_room_member_list_.*", + "screen\\.room_member_list\\..*", "screen_room_notification_settings_.*", "screen_notification_settings_edit_failed_updating_default_mode", "screen_polls_history_title", From fdfc5df365daa77ae6cbb8927eccf079dd8415d0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 08:59:17 +0100 Subject: [PATCH 038/113] fix(deps): update datastore to v1.2.0 (#5789) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3a5ac4046d..593aaa2d70 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,7 @@ firebaseAppDistribution = "5.2.0" # AndroidX core = "1.17.0" -datastore = "1.1.7" +datastore = "1.2.0" constraintlayout = "2.2.1" constraintlayout_compose = "1.1.1" lifecycle = "2.9.2" From 3411420efa2d8574d3bf3a3085ec455a00480232 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 10:13:34 +0100 Subject: [PATCH 039/113] chore(deps): update peter-evans/create-pull-request action to v7.0.9 (#5793) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/sync-localazy.yml | 2 +- .github/workflows/sync-sas-strings.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/sync-localazy.yml b/.github/workflows/sync-localazy.yml index 1f22bf2868..404af92f30 100644 --- a/.github/workflows/sync-localazy.yml +++ b/.github/workflows/sync-localazy.yml @@ -36,7 +36,7 @@ jobs: ./tools/localazy/importSupportedLocalesFromLocalazy.py ./tools/test/generateAllScreenshots.py - name: Create Pull Request for Strings - uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 + uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9 with: token: ${{ secrets.DANGER_GITHUB_API_TOKEN }} commit-message: Sync Strings from Localazy diff --git a/.github/workflows/sync-sas-strings.yml b/.github/workflows/sync-sas-strings.yml index a73592466e..e461845c9c 100644 --- a/.github/workflows/sync-sas-strings.yml +++ b/.github/workflows/sync-sas-strings.yml @@ -23,7 +23,7 @@ jobs: - name: Run SAS String script run: ./tools/sas/import_sas_strings.py - name: Create Pull Request for SAS Strings - uses: peter-evans/create-pull-request@271a8d0340265f705b14b6d32b9829c1cb33d45e # v7.0.8 + uses: peter-evans/create-pull-request@84ae59a2cdc2258d6fa0732dd66352dddae2a412 # v7.0.9 with: commit-message: Sync SAS Strings title: Sync SAS Strings From 8b7355705adcd41628542f7ff14d72e4c80734b8 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 24 Nov 2025 10:42:03 +0100 Subject: [PATCH 040/113] change(members): new empty state for search and hide banned tabs when there is none. --- .../impl/members/RoomMemberListPresenter.kt | 18 ++-- .../impl/members/RoomMemberListState.kt | 17 +++- .../members/RoomMemberListStateProvider.kt | 1 + .../impl/members/RoomMemberListView.kt | 99 ++++++++++--------- .../impl/src/main/res/values/localazy.xml | 2 + 5 files changed, 79 insertions(+), 58 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt index 44e0aa168f..3d59b3d922 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt @@ -49,7 +49,6 @@ import kotlinx.coroutines.withContext @Inject class RoomMemberListPresenter( private val room: JoinedRoom, - private val roomMemberListDataSource: RoomMemberListDataSource, private val coroutineDispatchers: CoroutineDispatchers, private val roomMembersModerationPresenter: Presenter, private val encryptionService: EncryptionService, @@ -141,20 +140,21 @@ class RoomMemberListPresenter( } } - if (!roomModerationState.canBan && selectedSection == SelectedSection.BANNED) { - SideEffect { - selectedSection = SelectedSection.MEMBERS - } - } - - return RoomMemberListState( - roomMembers = filteredRoomMembers, + val state = RoomMemberListState( + roomMembers = roomMembers, + filteredRoomMembers = filteredRoomMembers, searchQuery = searchQuery, canInvite = canInvite, moderationState = roomModerationState, selectedSection = selectedSection, eventSink = ::handleEvent, ) + if (!state.showBannedSection && selectedSection == SelectedSection.BANNED) { + SideEffect { + selectedSection = SelectedSection.MEMBERS + } + } + return state } private suspend fun RoomMember.withIdentityState(identityStates: ImmutableMap): RoomMemberWithIdentityState { diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt index b59f67a915..007d276dd3 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListState.kt @@ -17,13 +17,17 @@ import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList data class RoomMemberListState( - val roomMembers: AsyncData, + // Only used to know if we can show the banned section + private val roomMembers: AsyncData, + val filteredRoomMembers: AsyncData, val searchQuery: String, val canInvite: Boolean, val selectedSection: SelectedSection, val moderationState: RoomMemberModerationState, val eventSink: (RoomMemberListEvents) -> Unit, -) +) { + val showBannedSection: Boolean = moderationState.canBan && roomMembers.dataOrNull()?.banned?.isNotEmpty() == true +} enum class SelectedSection { MEMBERS, @@ -34,7 +38,14 @@ data class RoomMembers( val invited: ImmutableList, val joined: ImmutableList, val banned: ImmutableList, -){ +) { + fun isEmpty(section: SelectedSection): Boolean { + return when (section) { + SelectedSection.MEMBERS -> invited.isEmpty() && joined.isEmpty() + SelectedSection.BANNED -> banned.isEmpty() + } + } + fun filter(query: String): RoomMembers { if (query.isBlank()) { return this diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt index dafe2546d5..b03faa97cb 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt @@ -132,6 +132,7 @@ internal fun aRoomMemberListState( selectedSection: SelectedSection = SelectedSection.MEMBERS, ) = RoomMemberListState( roomMembers = roomMembers, + filteredRoomMembers = roomMembers, searchQuery = "", canInvite = false, moderationState = moderationState, diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt index 74d3305ff5..41db02ee9d 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt @@ -9,14 +9,15 @@ package io.element.android.features.roomdetails.impl.members import androidx.compose.animation.AnimatedVisibility +import androidx.compose.animation.expandHorizontally import androidx.compose.animation.expandVertically import androidx.compose.animation.fadeIn import androidx.compose.animation.fadeOut +import androidx.compose.animation.shrinkHorizontally import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement -import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.Row import androidx.compose.foundation.layout.consumeWindowInsets @@ -43,6 +44,8 @@ import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.roomdetails.impl.R import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.designsystem.atomic.molecules.IconTitleSubtitleMolecule +import io.element.android.libraries.designsystem.components.BigIcon import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.form.textFieldState @@ -87,9 +90,9 @@ fun RoomMemberListView( ) { padding -> Column( modifier = Modifier - .fillMaxWidth() - .padding(padding) - .consumeWindowInsets(padding), + .fillMaxWidth() + .padding(padding) + .consumeWindowInsets(padding), verticalArrangement = Arrangement.spacedBy(16.dp), ) { var searchQuery by textFieldState(state.searchQuery) @@ -100,15 +103,16 @@ fun RoomMemberListView( state.eventSink(RoomMemberListEvents.UpdateSearchQuery(newQuery)) }, modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp), + .fillMaxWidth() + .padding(horizontal = 16.dp), placeholder = stringResource(CommonStrings.common_search_for_someone), ) RoomMemberList( - roomMembers = state.roomMembers, + roomMembersData = state.filteredRoomMembers, selectedSection = state.selectedSection, + showBannedSection = state.showBannedSection, + searchQuery = state.searchQuery, onSelectedSectionChange = { state.eventSink(RoomMemberListEvents.ChangeSelectedSection(it)) }, - showSections = state.moderationState.canBan, onSelectUser = ::onSelectUser, ) } @@ -117,25 +121,26 @@ fun RoomMemberListView( @Composable private fun RoomMemberList( - roomMembers: AsyncData, + roomMembersData: AsyncData, selectedSection: SelectedSection, - showSections: Boolean = true, + showBannedSection: Boolean, + searchQuery: String, onSelectedSectionChange: (SelectedSection) -> Unit, onSelectUser: (RoomMember) -> Unit, ) { LazyColumn(modifier = Modifier.fillMaxWidth(), state = rememberLazyListState()) { stickyHeader { Column { - if (showSections) { + AnimatedVisibility(visible = showBannedSection) { val segmentedButtonTitles = persistentListOf( stringResource(id = R.string.screen_room_member_list_mode_members), stringResource(id = R.string.screen_room_member_list_mode_banned), ) SingleChoiceSegmentedButtonRow( modifier = Modifier - .background(ElementTheme.colors.bgCanvasDefault) - .fillMaxWidth() - .padding(start = 16.dp, end = 16.dp, bottom = 16.dp), + .background(ElementTheme.colors.bgCanvasDefault) + .fillMaxWidth() + .padding(start = 16.dp, end = 16.dp, bottom = 16.dp), ) { for ((index, title) in segmentedButtonTitles.withIndex()) { SegmentedButton( @@ -148,23 +153,26 @@ private fun RoomMemberList( } } } - AnimatedVisibility( - visible = roomMembers.isLoading(), - enter = fadeIn() + expandVertically(), - exit = fadeOut() + shrinkVertically(), - ) { + AnimatedVisibility(visible = roomMembersData.isLoading()) { LinearProgressIndicator(modifier = Modifier.fillMaxWidth()) } } } - when (roomMembers) { - is AsyncData.Failure -> failureItem(roomMembers.error) + when (roomMembersData) { + is AsyncData.Failure -> failureItem(roomMembersData.error) is AsyncData.Loading, - is AsyncData.Success -> memberItems( - roomMembers = roomMembers.dataOrNull() ?: return@LazyColumn, - selectedSection = selectedSection, - onSelectUser = onSelectUser, - ) + is AsyncData.Success -> { + val roomMembers = roomMembersData.dataOrNull() ?: return@LazyColumn + if (roomMembers.isEmpty(selectedSection)) { + emptySearchItem(searchQuery) + } else { + memberItems( + roomMembers = roomMembers, + selectedSection = selectedSection, + onSelectUser = onSelectUser, + ) + } + } AsyncData.Uninitialized -> Unit } } @@ -202,7 +210,7 @@ private fun LazyListScope.memberItems( ) } } - SelectedSection.BANNED -> { // Banned users + SelectedSection.BANNED -> { if (roomMembers.banned.isNotEmpty()) { roomMemberListSectionHeader( text = { @@ -215,23 +223,6 @@ private fun LazyListScope.memberItems( members = roomMembers.banned, onMemberSelected = { onSelectUser(it) } ) - } else { - item { - Box( - Modifier - .fillParentMaxSize() - .padding(horizontal = 16.dp) - ) { - Text( - modifier = Modifier - .padding(bottom = 56.dp) - .align(Alignment.Center), - text = stringResource(id = R.string.screen_room_member_list_banned_empty), - color = ElementTheme.colors.textSecondary, - textAlign = TextAlign.Center, - ) - } - } } } } @@ -241,8 +232,8 @@ private fun LazyListScope.failureItem(failure: Throwable) { item { Text( modifier = Modifier - .fillMaxWidth() - .padding(horizontal = 16.dp, vertical = 32.dp), + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 32.dp), text = stringResource(id = CommonStrings.error_unknown) + "\n\n" + failure.localizedMessage, color = ElementTheme.colors.textCriticalPrimary, textAlign = TextAlign.Center, @@ -278,6 +269,22 @@ private fun LazyListScope.roomMemberListSectionItems( } } +private fun LazyListScope.emptySearchItem(searchQuery: String) { + item { + IconTitleSubtitleMolecule( + modifier = Modifier + .fillMaxWidth() + .padding(horizontal = 16.dp, vertical = 32.dp), + iconStyle = BigIcon.Style.Default( + vectorIcon = CompoundIcons.Search(), + contentDescription = null, + ), + title = stringResource(R.string.screen_room_member_list_empty_search_title, searchQuery), + subTitle = stringResource(R.string.screen_room_member_list_empty_search_subtitle), + ) + } +} + @Composable private fun RoomMemberListItem( roomMemberWithIdentity: RoomMemberWithIdentityState, diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index 4d8e634e81..a88f910de9 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -72,6 +72,8 @@ "Updating room…" "There are no banned users." "%1$d Banned" + "Check the spelling or try a new search" + "No results for “%1$s”" "%1$d Person" "%1$d People" From 444a61f88986cb3200f6521518bd634359e5151a Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 15:12:57 +0100 Subject: [PATCH 041/113] fix(deps): update dependency io.nlopez.compose.rules:detekt to v0.4.28 (#5795) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- build.gradle.kts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle.kts b/build.gradle.kts index ef12d98fd3..19aaf78405 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -46,7 +46,7 @@ allprojects { config.from(files("$rootDir/tools/detekt/detekt.yml")) } dependencies { - detektPlugins("io.nlopez.compose.rules:detekt:0.4.27") + detektPlugins("io.nlopez.compose.rules:detekt:0.4.28") detektPlugins(project(":tests:detekt-rules")) } From 8a4bdfa1fdf4af4bfd2c341fe2508b3eaeee6f2f Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Mon, 24 Nov 2025 14:15:59 +0000 Subject: [PATCH 042/113] fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.11.24 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 593aaa2d70..6986e3577e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -178,7 +178,7 @@ test_detekt_test = { module = "io.gitlab.arturbosch.detekt:detekt-test", version # https://github.com/matrix-org/matrix-rust-components-kotlin/commits/main/sdk/sdk-android/src/main/kotlin/org/matrix/rustcomponents/sdk/matrix_sdk_ffi.kt # All new features should not be implemented in the pull request that upgrades the version, developers should # only fix API breaks and may add some TODOs. -matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.11.19" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.11.24" # Others coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } From eff221645e984373487b6c26145336813e5764e8 Mon Sep 17 00:00:00 2001 From: ElementBot <110224175+ElementBot@users.noreply.github.com> Date: Mon, 24 Nov 2025 17:28:49 +0100 Subject: [PATCH 043/113] Sync Strings (#5792) * Sync Strings from Localazy * Update localazy config and sync strings. * Use the new localazy key. * Sync strings again * Sync strings again and fix compilation issue. * Update screenshots --------- Co-authored-by: bmarty <3940906+bmarty@users.noreply.github.com> Co-authored-by: Benoit Marty --- .../src/main/res/values-bg/translations.xml | 4 + .../impl/roles/ChangeRolesView.kt | 2 +- .../src/main/res/values-be/translations.xml | 1 - .../src/main/res/values-bg/translations.xml | 1 + .../src/main/res/values-cs/translations.xml | 1 - .../src/main/res/values-cy/translations.xml | 1 - .../src/main/res/values-da/translations.xml | 1 - .../src/main/res/values-de/translations.xml | 1 - .../src/main/res/values-el/translations.xml | 1 - .../src/main/res/values-es/translations.xml | 1 - .../src/main/res/values-et/translations.xml | 4 +- .../src/main/res/values-eu/translations.xml | 1 - .../src/main/res/values-fa/translations.xml | 1 - .../src/main/res/values-fi/translations.xml | 1 - .../src/main/res/values-fr/translations.xml | 1 - .../src/main/res/values-hu/translations.xml | 2 +- .../src/main/res/values-in/translations.xml | 1 - .../src/main/res/values-it/translations.xml | 1 - .../src/main/res/values-ka/translations.xml | 1 - .../src/main/res/values-ko/translations.xml | 1 - .../src/main/res/values-lt/translations.xml | 1 - .../src/main/res/values-nb/translations.xml | 1 - .../src/main/res/values-nl/translations.xml | 1 - .../src/main/res/values-pl/translations.xml | 1 - .../main/res/values-pt-rBR/translations.xml | 1 - .../src/main/res/values-pt/translations.xml | 1 - .../src/main/res/values-ro/translations.xml | 1 - .../src/main/res/values-ru/translations.xml | 4 +- .../src/main/res/values-sk/translations.xml | 1 - .../src/main/res/values-sv/translations.xml | 1 - .../src/main/res/values-tr/translations.xml | 1 - .../src/main/res/values-uk/translations.xml | 1 - .../src/main/res/values-ur/translations.xml | 1 - .../src/main/res/values-uz/translations.xml | 1 - .../main/res/values-zh-rTW/translations.xml | 26 +- .../src/main/res/values-zh/translations.xml | 1 - .../impl/src/main/res/values/localazy.xml | 16 +- .../impl/members/RoomMemberListView.kt | 6 +- .../src/main/res/values-be/translations.xml | 1 - .../src/main/res/values-cs/translations.xml | 2 - .../src/main/res/values-cy/translations.xml | 2 - .../src/main/res/values-da/translations.xml | 2 - .../src/main/res/values-de/translations.xml | 2 - .../src/main/res/values-el/translations.xml | 2 - .../src/main/res/values-es/translations.xml | 2 - .../src/main/res/values-et/translations.xml | 15 +- .../src/main/res/values-eu/translations.xml | 1 - .../src/main/res/values-fa/translations.xml | 1 - .../src/main/res/values-fi/translations.xml | 2 - .../src/main/res/values-fr/translations.xml | 2 - .../src/main/res/values-hu/translations.xml | 13 +- .../src/main/res/values-in/translations.xml | 2 - .../src/main/res/values-it/translations.xml | 2 - .../src/main/res/values-ka/translations.xml | 1 - .../src/main/res/values-ko/translations.xml | 2 - .../src/main/res/values-lt/translations.xml | 1 - .../src/main/res/values-nb/translations.xml | 2 - .../src/main/res/values-nl/translations.xml | 1 - .../src/main/res/values-pl/translations.xml | 1 - .../main/res/values-pt-rBR/translations.xml | 2 - .../src/main/res/values-pt/translations.xml | 2 - .../src/main/res/values-ro/translations.xml | 2 - .../src/main/res/values-ru/translations.xml | 13 +- .../src/main/res/values-sk/translations.xml | 2 - .../src/main/res/values-sv/translations.xml | 2 - .../src/main/res/values-tr/translations.xml | 2 - .../src/main/res/values-uk/translations.xml | 2 - .../src/main/res/values-ur/translations.xml | 1 - .../src/main/res/values-uz/translations.xml | 1 - .../main/res/values-zh-rTW/translations.xml | 53 +- .../src/main/res/values-zh/translations.xml | 2 - .../impl/src/main/res/values/localazy.xml | 18 +- .../main/res/values-zh-rTW/translations.xml | 4 +- .../main/res/values-zh-rTW/translations.xml | 2 +- .../src/main/res/values-bg/translations.xml | 7 + .../main/res/values-zh-rTW/translations.xml | 1 + .../src/main/res/values-bg/translations.xml | 15 + .../main/res/values-zh-rTW/translations.xml | 5 + ...s.impl.roles_ChangeRolesView_Day_13_de.png | 3 + screenshots/html/data.js | 1855 +++++++++-------- ...pl.members_RoomMemberListView_Day_0_en.png | 4 +- ...pl.members_RoomMemberListView_Day_1_en.png | 4 +- ...pl.members_RoomMemberListView_Day_7_en.png | 4 +- ....members_RoomMemberListView_Night_0_en.png | 4 +- ....members_RoomMemberListView_Night_1_en.png | 4 +- ....members_RoomMemberListView_Night_7_en.png | 4 +- ...rivacy_SecurityAndPrivacyViewDark_1_en.png | 4 +- ...rivacy_SecurityAndPrivacyViewDark_2_en.png | 4 +- ...rivacy_SecurityAndPrivacyViewDark_3_en.png | 4 +- ...rivacy_SecurityAndPrivacyViewDark_4_en.png | 4 +- ...rivacy_SecurityAndPrivacyViewDark_9_en.png | 4 +- ...ivacy_SecurityAndPrivacyViewLight_1_en.png | 4 +- ...ivacy_SecurityAndPrivacyViewLight_2_en.png | 4 +- ...ivacy_SecurityAndPrivacyViewLight_3_en.png | 4 +- ...ivacy_SecurityAndPrivacyViewLight_4_en.png | 4 +- ...ivacy_SecurityAndPrivacyViewLight_9_en.png | 4 +- tools/localazy/config.json | 4 +- 97 files changed, 1109 insertions(+), 1106 deletions(-) create mode 100644 features/announcement/impl/src/main/res/values-bg/translations.xml create mode 100644 screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_de.png diff --git a/features/announcement/impl/src/main/res/values-bg/translations.xml b/features/announcement/impl/src/main/res/values-bg/translations.xml new file mode 100644 index 0000000000..853cf5f027 --- /dev/null +++ b/features/announcement/impl/src/main/res/values-bg/translations.xml @@ -0,0 +1,4 @@ + + + "Присъединете се към обществени пространства" + diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt index 76cb334037..bd9969dec4 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt @@ -383,7 +383,7 @@ private fun MemberRow( if (isPending) { Text( modifier = Modifier.padding(start = 8.dp), - text = stringResource(id = R.string.screen_room_member_list_pending_header_title), + text = stringResource(id = R.string.screen_room_member_list_pending_status), style = ElementTheme.typography.fontBodySmRegular.copy(fontStyle = FontStyle.Italic), color = ElementTheme.colors.textSecondary ) diff --git a/features/rolesandpermissions/impl/src/main/res/values-be/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-be/translations.xml index 7b11b6ee44..44841d1207 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-be/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-be/translations.xml @@ -39,7 +39,6 @@ "Яны змогуць зноў далучыцца да гэтага пакоя, калі іх запросяць." "Заблакіраваныя" "Удзельнікі" - "У чаканні" "Толькі адміністратары" "Адміністратары і мадэратары" "Удзельнікі пакоя" diff --git a/features/rolesandpermissions/impl/src/main/res/values-bg/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-bg/translations.xml index 4f135baa44..b1ca5f9718 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-bg/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-bg/translations.xml @@ -33,5 +33,6 @@ "Нулиране на разрешенията" "Роли" "Подробности за стаята" + "Подробности за пространството" "Роли и разрешения" diff --git a/features/rolesandpermissions/impl/src/main/res/values-cs/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-cs/translations.xml index 829c6f31e2..67e65142d8 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-cs/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-cs/translations.xml @@ -44,7 +44,6 @@ "Zrušit vykázání z místnosti" "Vykázaní" "Členové" - "Nevyřízeno" "Pouze správci" "Správci a moderátoři" "Vlastník" diff --git a/features/rolesandpermissions/impl/src/main/res/values-cy/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-cy/translations.xml index 760586331c..f75f908d43 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-cy/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-cy/translations.xml @@ -49,7 +49,6 @@ "Dad-wahardd o\'r ystafell" "Wedi\'i wahardd" "Aelodau" - "Dan ystyriaeth" "Gweinyddwyr yn unig" "Gweinyddwyr a chymedrolwyr" "Perchennog" diff --git a/features/rolesandpermissions/impl/src/main/res/values-da/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-da/translations.xml index 449fd4523f..4a0b5d179d 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-da/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-da/translations.xml @@ -43,7 +43,6 @@ "Fjern brugerens spærring fra rummet" "Spærret" "Medlemmer" - "Afventer" "Kun admins" "Admins og moderatorer" "Ejeren" diff --git a/features/rolesandpermissions/impl/src/main/res/values-de/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-de/translations.xml index 0630721472..2767781d2b 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-de/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-de/translations.xml @@ -43,7 +43,6 @@ "Sperre für diesen Chat aufheben" "Gesperrt" "Mitglieder" - "Ausstehend" "Nur Admins" "Admins und Moderatoren" "Eigentümer" diff --git a/features/rolesandpermissions/impl/src/main/res/values-el/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-el/translations.xml index fd7ddaa60e..8cd14feb47 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-el/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-el/translations.xml @@ -39,7 +39,6 @@ "Άρση αποκλεισμού από την αίθουσα" "Αποκλεισμένοι" "Μέλη" - "Σε αναμονή" "Μόνο διαχειριστές" "Διαχειριστές και συντονιστές" "Μέλη της αίθουσας" diff --git a/features/rolesandpermissions/impl/src/main/res/values-es/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-es/translations.xml index b981a18c73..383ffba1eb 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-es/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-es/translations.xml @@ -39,7 +39,6 @@ "Eliminar veto en la sala" "Vetados" "Miembros" - "Pendiente" "Solo administradores" "Administradores y moderadores" "Miembros de la sala" diff --git a/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml index 5bd0c3eb36..7924e7ce7b 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-et/translations.xml @@ -34,6 +34,8 @@ "Sul on salvestamata muudatusi" "Kas salvestame muudatused?" "Suhtluskeeluga kasutajaid pole" + "Palun kontrolli otsingusõna korrektsust ja proovi siis uuesti" + "Otsingul „%1$s“ pole tulemusi" "%1$d osaleja" "%1$d osalejat" @@ -45,7 +47,7 @@ "Eemalda suhtluskeeld jututoas" "Suhtluskeeluga kasutajad" "Liikmed" - "Ootel" + "Ootel" "Peakasutajad" "Moderaatorid" "Omanik" diff --git a/features/rolesandpermissions/impl/src/main/res/values-eu/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-eu/translations.xml index a1f084a44a..03766f73f2 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-eu/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-eu/translations.xml @@ -38,7 +38,6 @@ "Kendu debekua" "Debekatuta" "Kideak" - "Zain" "Administratzaileak soilik" "Administratzaileak eta moderatzaileak" "Jabea" diff --git a/features/rolesandpermissions/impl/src/main/res/values-fa/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-fa/translations.xml index 43ee4b03ca..996b50bf62 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-fa/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-fa/translations.xml @@ -40,7 +40,6 @@ "تحریم نکردن از اتاق" "محروم" "اعضا" - "منتظر" "فقط مدیران" "مدیرن و ناظران" "مالک" diff --git a/features/rolesandpermissions/impl/src/main/res/values-fi/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-fi/translations.xml index e86182c483..658828ae41 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-fi/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-fi/translations.xml @@ -43,7 +43,6 @@ "Poista porttikielto huoneesta" "Porttikiellot" "Jäsenet" - "Kutsuttu" "Vain ylläpitäjät" "Ylläpitäjät ja valvojat" "Omistaja" diff --git a/features/rolesandpermissions/impl/src/main/res/values-fr/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-fr/translations.xml index b3258ef02d..36add59a2d 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-fr/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-fr/translations.xml @@ -45,7 +45,6 @@ "Débannir du salon" "Bannis" "Membres" - "En attente" "Administrateurs" "Modérateurs" "Propriétaire" diff --git a/features/rolesandpermissions/impl/src/main/res/values-hu/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-hu/translations.xml index 72ab09db6a..77e6e3b389 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-hu/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-hu/translations.xml @@ -45,7 +45,7 @@ "Visszaengedés a szobába" "Kitiltva" "Tagok" - "Függőben" + "Függőben" "Adminisztrátor" "Moderátor" "Tulajdonos" diff --git a/features/rolesandpermissions/impl/src/main/res/values-in/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-in/translations.xml index 46913b323d..2a1cd15ac0 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-in/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-in/translations.xml @@ -38,7 +38,6 @@ "Batalkan cekalan dari ruangan" "Tercekal" "Anggota" - "Tertunda" "Hanya admin" "Admin dan moderator" "Anggota ruangan" diff --git a/features/rolesandpermissions/impl/src/main/res/values-it/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-it/translations.xml index f5799aceab..6b11b7946b 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-it/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-it/translations.xml @@ -43,7 +43,6 @@ "Riammetti nella stanza" "Esclusi" "Membri" - "In attesa" "Solo amministratori" "Amministratori e moderatori" "Proprietario" diff --git a/features/rolesandpermissions/impl/src/main/res/values-ka/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-ka/translations.xml index bdb3a70069..8af9ecbe99 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-ka/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-ka/translations.xml @@ -37,7 +37,6 @@ "მოწვევის შემთხვევაში განბლოკილი მომხმარებელი ისევ შეძლებს ოთახს შეუერთდეს." "დაბლოკილები" "წევრები" - "მომლოდინე" "მხოლოდ ადმინისტრატორები" "ადმინისტრატორები და მოდერატორები" "ოთახის წევრები" diff --git a/features/rolesandpermissions/impl/src/main/res/values-ko/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-ko/translations.xml index 86b3f828f5..89b3e0baf5 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-ko/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-ko/translations.xml @@ -42,7 +42,6 @@ "방에서 차단 해제" "차단됨" "회원들" - "보류 중" "관리자 전용" "관리자 및 중재자" "소유자" diff --git a/features/rolesandpermissions/impl/src/main/res/values-lt/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-lt/translations.xml index 0ebff0f6b0..b82e8822f5 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-lt/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-lt/translations.xml @@ -6,6 +6,5 @@ "%1$d asmenys" "%1$d asmenų" - "Laukiama" "Kambario nariai" diff --git a/features/rolesandpermissions/impl/src/main/res/values-nb/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-nb/translations.xml index 045f2e2327..65664c187a 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-nb/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-nb/translations.xml @@ -43,7 +43,6 @@ "Fjern utestengelsen fra rommet" "Utestengt" "Medlemmer" - "Venter" "Kun for administratorer" "Administratorer og moderatorer" "Eier" diff --git a/features/rolesandpermissions/impl/src/main/res/values-nl/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-nl/translations.xml index 2d5e8e4a01..2973341189 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-nl/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-nl/translations.xml @@ -38,7 +38,6 @@ "Ze kunnen opnieuw tot de kamer toetreden als ze worden uitgenodigd." "Verbannen" "Leden" - "In behandeling" "Alleen beheerders" "Beheerders en moderators" "Kamerleden" diff --git a/features/rolesandpermissions/impl/src/main/res/values-pl/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-pl/translations.xml index a8722a7f77..44659c47cd 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-pl/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-pl/translations.xml @@ -44,7 +44,6 @@ "Odbanuj z pokoju" "Zbanowanych" "Członków" - "Oczekujące" "Tylko administratorzy" "Administratorzy i moderatorzy" "Właściciel" diff --git a/features/rolesandpermissions/impl/src/main/res/values-pt-rBR/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-pt-rBR/translations.xml index cabe3e486e..ec2e5bc558 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-pt-rBR/translations.xml @@ -43,7 +43,6 @@ "Desbanir da sala" "Banidos" "Membros" - "Pendente" "Somente administradores" "Administradores e moderadores" "Proprietário" diff --git a/features/rolesandpermissions/impl/src/main/res/values-pt/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-pt/translations.xml index c9ed317736..32db66ee12 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-pt/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-pt/translations.xml @@ -43,7 +43,6 @@ "Desbanir da sala" "Banidos" "Participantes" - "Pendente" "Apenas administradores" "Administradores e moderadores" "Dono / Dona" diff --git a/features/rolesandpermissions/impl/src/main/res/values-ro/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-ro/translations.xml index 5d0c164ea5..c2b248f264 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-ro/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-ro/translations.xml @@ -43,7 +43,6 @@ "Revocati excluderea din camera" "Excluși" "Membri" - "În așteptare" "Doar administratori" "Administratori și moderatori" "Proprietar" diff --git a/features/rolesandpermissions/impl/src/main/res/values-ru/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-ru/translations.xml index 54d0299df2..f54b984ea3 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-ru/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-ru/translations.xml @@ -34,6 +34,8 @@ "У вас есть несохраненные изменения." "Сохранить изменения?" "В этой комнате нет заблокированных пользователей." + "Проверьте правописание или попробуйте новый поиск" + "Отсутствует результат по запросу “%1$s”" "%1$d пользователь" "%1$d пользователя" @@ -46,7 +48,7 @@ "Разблокировать в комнате" "Заблокированные" "Участники" - "В ожидании" + "В ожидании" "Только администраторы" "Модератор" "Владелец" diff --git a/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml index 3815deaed2..a707b48bc5 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-sk/translations.xml @@ -44,7 +44,6 @@ "Zrušiť zákaz prístupu do miestnosti" "Zakázaní" "Členovia" - "Čaká sa" "Iba správcovia" "Správcovia a moderátori" "Vlastník" diff --git a/features/rolesandpermissions/impl/src/main/res/values-sv/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-sv/translations.xml index 721c50bfde..d52c85de14 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-sv/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-sv/translations.xml @@ -43,7 +43,6 @@ "Avbanna från rummet" "Bannade" "Medlemmar" - "Väntar" "Endast administratörer" "Administratörer och moderatorer" "Ägare" diff --git a/features/rolesandpermissions/impl/src/main/res/values-tr/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-tr/translations.xml index 827972fb5a..6e53f48610 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-tr/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-tr/translations.xml @@ -38,7 +38,6 @@ "Davet edildikleri takdirde bu odaya tekrar katılabileceklerdir." "Yasaklandı" "Üyeler" - "Beklemede" "Yalnızca yöneticiler" "Yöneticiler ve moderatörler" "Oda üyeleri" diff --git a/features/rolesandpermissions/impl/src/main/res/values-uk/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-uk/translations.xml index 99ba8cb1d5..9eae3a94e6 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-uk/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-uk/translations.xml @@ -44,7 +44,6 @@ "Розблокувати в кімнаті" "Заблоковані" "Учасники" - "На розгляді" "Тільки для адміністраторів" "Адміністратори та модератори" "Власник" diff --git a/features/rolesandpermissions/impl/src/main/res/values-ur/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-ur/translations.xml index 944f4f463f..8e6e47f4aa 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-ur/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-ur/translations.xml @@ -38,7 +38,6 @@ "اگر وہ مدعو کیا جائیں تو وہ دوبارہ اس کمرے میں شامل ہوسکیں گے۔" "محظور" "اراکین" - "زیر التواء" "صرف منتظمین" "منتظمین اور ناظمین" "کمرے کے ارکان" diff --git a/features/rolesandpermissions/impl/src/main/res/values-uz/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-uz/translations.xml index 943eb9ba4f..61329b8577 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-uz/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-uz/translations.xml @@ -38,7 +38,6 @@ "Agar taklif qilinsa, ular bu xonaga qayta qo‘shilishlari mumkin." "Taqiqlangan" "Azolar" - "Kutilmoqda" "Faqat adminlar" "Adminlar va moderatorlar" "Xona a\'zolari" diff --git a/features/rolesandpermissions/impl/src/main/res/values-zh-rTW/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-zh-rTW/translations.xml index 8ead85796f..50555bf9ed 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-zh-rTW/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-zh-rTW/translations.xml @@ -1,14 +1,16 @@ - "僅限管理員" + "管理員" "管理黑名單" "移除訊息" - "邀請夥伴並接受加入請求" + "成員" + "邀請夥伴" + "管理成員" "訊息與內容" - "管理員和版主" - "移除夥伴並拒絕加入請求" + "版主" + "移除夥伴" "變更聊天室大頭照" - "編輯聊天室" + "編輯詳細資訊" "變更聊天室名稱" "變更聊天室主題" "傳送訊息" @@ -32,8 +34,10 @@ "您有尚未儲存的變更" "是否儲存變更?" "沒有被封鎖的使用者。" + "檢查拼字或嘗試新搜尋" + "找不到「%1$s」" - "%1$d 位夥伴" + "%1$d 個人" "踢出並加入黑名單" "僅移除成員" @@ -42,9 +46,9 @@ "從聊天室解除封鎖" "黑名單" "成員" - "待定" - "僅限管理員" - "管理員和版主" + "擱置中" + "管理員" + "版主" "擁有者" "聊天室成員" "正在解除黑名單 %1$s" @@ -57,10 +61,12 @@ "訊息與內容" "版主" "擁有者" + "權限" "重設權限" "重設之後,您會遺失當前的設定。" "確定要重設權限嗎?" "身份" "聊天室資訊" - "身份與權限" + "空間詳細資訊" + "角色與權限" diff --git a/features/rolesandpermissions/impl/src/main/res/values-zh/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-zh/translations.xml index ba5df3de15..3a11398599 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-zh/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-zh/translations.xml @@ -42,7 +42,6 @@ "从房间取消解封" "已封禁用户" "成员" - "待处理" "仅限管理员" "管理员和协管员" "所有者" diff --git a/features/rolesandpermissions/impl/src/main/res/values/localazy.xml b/features/rolesandpermissions/impl/src/main/res/values/localazy.xml index 2d98f43f97..70efa48e5a 100644 --- a/features/rolesandpermissions/impl/src/main/res/values/localazy.xml +++ b/features/rolesandpermissions/impl/src/main/res/values/localazy.xml @@ -34,9 +34,15 @@ "You have unsaved changes." "Save changes?" "There are no banned users." + + "%1$d Banned" + "%1$d Banned" + + "Check the spelling or try a new search" + "No results for “%1$s”" - "%1$d person" - "%1$d people" + "%1$d Person" + "%1$d People" "Ban user" "Only remove member" @@ -45,7 +51,11 @@ "Unban user" "Banned" "Members" - "Pending" + + "%1$d Invited" + "%1$d Invited" + + "Pending" "Admin" "Moderator" "Owner" diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt index 2b1ebb175c..15c89ee9a7 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt @@ -202,7 +202,11 @@ private fun LazyListScope.memberItems( SelectedSection.MEMBERS -> { if (roomMembers.invited.isNotEmpty()) { roomMemberListSection( - headerText = { stringResource(id = R.string.screen_room_member_list_pending_header_title) }, + headerText = { + // TODO Use showMembersCount? iOS seems to always render the number of users, even when searching for users. + val invitedCount = roomMembers.invited.count() + pluralStringResource(id = R.plurals.screen_room_member_list_pending_header_title, count = invitedCount, invitedCount) + }, members = roomMembers.invited, onMemberSelected = { onSelectUser(it) } ) diff --git a/features/roomdetails/impl/src/main/res/values-be/translations.xml b/features/roomdetails/impl/src/main/res/values-be/translations.xml index 74be3a0362..fe337177df 100644 --- a/features/roomdetails/impl/src/main/res/values-be/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-be/translations.xml @@ -69,7 +69,6 @@ "Яны змогуць зноў далучыцца да гэтага пакоя, калі іх запросяць." "Заблакіраваныя" "Удзельнікі" - "У чаканні" "Толькі адміністратары" "Адміністратары і мадэратары" "Удзельнікі пакоя" diff --git a/features/roomdetails/impl/src/main/res/values-cs/translations.xml b/features/roomdetails/impl/src/main/res/values-cs/translations.xml index df81622e48..6e1214eea0 100644 --- a/features/roomdetails/impl/src/main/res/values-cs/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-cs/translations.xml @@ -81,7 +81,6 @@ "Zrušit vykázání z místnosti" "Vykázaní" "Členové" - "Nevyřízeno" "Pouze správci" "Správci a moderátoři" "Vlastník" @@ -145,7 +144,6 @@ Nedoporučujeme povolovat šifrování pro místnosti, které může kdokoli naj "Adresy místností představují způsoby, jak najít místnosti a získat k nim přístup. Díky tomu můžete svoji místnost snadno sdílet s ostatními. Můžete se rozhodnout publikovat svou místnost ve veřejném adresáři místnosti vašeho domovského serveru." "Publikování místnosti" - "Adresy místností představují způsoby, jak najít místnosti a získat k nim přístup. Díky tomu můžete svoji místnost snadno sdílet s ostatními." "Viditelnost místnosti" "Zabezpečení a soukromí" diff --git a/features/roomdetails/impl/src/main/res/values-cy/translations.xml b/features/roomdetails/impl/src/main/res/values-cy/translations.xml index 8dcdb8abed..0a3c05285a 100644 --- a/features/roomdetails/impl/src/main/res/values-cy/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-cy/translations.xml @@ -86,7 +86,6 @@ "Dad-wahardd o\'r ystafell" "Wedi\'i wahardd" "Aelodau" - "Dan ystyriaeth" "Gweinyddwyr yn unig" "Gweinyddwyr a chymedrolwyr" "Perchennog" @@ -150,7 +149,6 @@ Nid ydym yn argymell galluogi amgryptio ar gyfer ystafelloedd y gall unrhyw un d "Mae cyfeiriadau ystafelloedd yn ffyrdd o ddod o hyd i ystafelloedd a chael mynediad iddyn nhw. Mae hyn hefyd yn sicrhau y gallwch chi rannu\'ch ystafell yn hawdd ag eraill. Gallwch ddewis cyhoeddi eich ystafell yng ngweinydd cartref eich cyfeiriadur ystafelloedd cyhoeddus." "Cyhoeddi ystafell" - "Mae cyfeiriadau ystafelloedd yn ffyrdd o ddod o hyd i ystafelloedd a chael mynediad iddyn nhw. Mae hyn hefyd yn sicrhau y gallwch chi rannu\'ch ystafell yn hawdd ag eraill." "Gwelededd yr ystafell" "Diogelwch a phreifatrwydd" diff --git a/features/roomdetails/impl/src/main/res/values-da/translations.xml b/features/roomdetails/impl/src/main/res/values-da/translations.xml index c77c740086..63a20e51ec 100644 --- a/features/roomdetails/impl/src/main/res/values-da/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-da/translations.xml @@ -80,7 +80,6 @@ "Fjern brugerens spærring fra rummet" "Spærret" "Medlemmer" - "Afventer" "Kun admins" "Admins og moderatorer" "Ejeren" @@ -143,6 +142,5 @@ Vi anbefaler ikke at aktivere kryptering for rum, som alle kan finde og deltage "Rum-adresser er en måde at finde og få adgang til værelser på. Dette sikrer også, at du nemt kan dele dit rum med andre. Du kan vælge at offentliggøre dit rum i din hjemmeservers offentlige katalog over rum." "Udgivelse af rum" - "Rum-adresser er måder at finde og få adgang til rum på. Dette sikrer også, at du nemt kan dele dit rum med andre." "Sikkerhed og privatliv" diff --git a/features/roomdetails/impl/src/main/res/values-de/translations.xml b/features/roomdetails/impl/src/main/res/values-de/translations.xml index 981abcb6db..ec71ebc015 100644 --- a/features/roomdetails/impl/src/main/res/values-de/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-de/translations.xml @@ -80,7 +80,6 @@ "Sperre für diesen Chat aufheben" "Gesperrt" "Mitglieder" - "Ausstehend" "Nur Admins" "Admins und Moderatoren" "Eigentümer" @@ -144,7 +143,6 @@ Wir empfehlen keine Verschlüsselung für Chats zu aktivieren, die jeder finden "Chat-Adressen machen es möglich, Chats zu finden und ihnen beizutreten. Dies erleichtert es, Chats mit anderen zu teilen. Auf Wunsch kannst du deinen Chat im öffentlichen Verzeichnis deines Homeservers veröffentlichen." "Veröffentlichung von Chats" - "Chat-Adressen machen es möglich, Chats zu finden und ihnen beizutreten. Dies erleichtert es, Chats mit anderen zu teilen." "Chatroomsichtbarkeit." "Sicherheit & Datenschutz" diff --git a/features/roomdetails/impl/src/main/res/values-el/translations.xml b/features/roomdetails/impl/src/main/res/values-el/translations.xml index d395d57a1a..0eadb5f775 100644 --- a/features/roomdetails/impl/src/main/res/values-el/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-el/translations.xml @@ -74,7 +74,6 @@ "Άρση αποκλεισμού από την αίθουσα" "Αποκλεισμένοι" "Μέλη" - "Σε αναμονή" "Μόνο διαχειριστές" "Διαχειριστές και συντονιστές" "Μέλη της αίθουσας" @@ -134,6 +133,5 @@ "Οι διευθύνσεις αιθουσών είναι τρόποι εύρεσης και πρόσβασης σε αίθουσες. Αυτό διασφαλίζει επίσης ότι μπορείτε εύκολα να μοιραστείτε την αίθουσα με άλλους. Μπορείτε να επιλέξετε να δημοσιεύσετε την αίθουσά σας στον δημόσιο κατάλογο αιθουσών του αρχικού διακομιστή σας." "Δημοσίευση αίθουσας" - "Οι διευθύνσεις αιθουσών είναι τρόποι εύρεσης και πρόσβασης σε αίθουσες. Αυτό εξασφαλίζει επίσης ότι μπορείτε εύκολα να μοιραστείτε την αίθουσα με άλλους." "Ασφάλεια & απόρρητο" diff --git a/features/roomdetails/impl/src/main/res/values-es/translations.xml b/features/roomdetails/impl/src/main/res/values-es/translations.xml index 6eb229dde1..d58ddcd598 100644 --- a/features/roomdetails/impl/src/main/res/values-es/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-es/translations.xml @@ -74,7 +74,6 @@ "Eliminar veto en la sala" "Vetados" "Miembros" - "Pendiente" "Solo administradores" "Administradores y moderadores" "Miembros de la sala" @@ -134,6 +133,5 @@ No recomendamos habilitar el cifrado para las salas que cualquiera pueda encontr "Las direcciones de sala son formas de buscar salas y acceder a ellas. Esto también garantiza que puedas compartir fácilmente tu sala con otras personas. Puedes optar por publicar tu sala en el directorio de salas públicas de tu servidor base." "Publicación de la sala" - "Las direcciones de sala son un medio para buscar y acceder a salas. También te permiten compartir fácilmente tu sala con otras personas." "Seguridad y privacidad" diff --git a/features/roomdetails/impl/src/main/res/values-et/translations.xml b/features/roomdetails/impl/src/main/res/values-et/translations.xml index c69e9cca8d..331bce4ba5 100644 --- a/features/roomdetails/impl/src/main/res/values-et/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-et/translations.xml @@ -71,6 +71,8 @@ "Teema" "Uuendame jututuba…" "Suhtluskeeluga kasutajaid pole" + "Palun kontrolli otsingusõna korrektsust ja proovi siis uuesti" + "Otsingul „%1$s“ pole tulemusi" "%1$d osaleja" "%1$d osalejat" @@ -82,7 +84,7 @@ "Eemalda suhtluskeeld jututoas" "Suhtluskeeluga kasutajad" "Liikmed" - "Ootel" + "Ootel" "Peakasutajad" "Moderaatorid" "Omanik" @@ -118,8 +120,8 @@ "Rollid" "Jututoa üksikasjad" "Rollid ja õigused" - "Lisa jututoa aadress" - "Kõik võivad paluda jututoaga liitumist, kuid peakasutaja peab sellega nõustuma." + "Lisa aadress" + "Kõik võivad paluda jututoaga liitumist." "Küsi võimalust liitumiseks" "Jah, lülita krüptimine sisse" "Kui jututoa krüptimine on kord sisse lülitatud, siis seda välja lülitada ei saa. Sõnumite ajalugu on nähtav vaid jututoa liikmetele alates kutse saamise või liitumise hetkest. @@ -132,12 +134,12 @@ Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega "Kõik võivad jututoaga liituda" "Kõik" "Liituda saab vaid kutse olemasolul" - "Privaatne" + "Vaid kutsega" "Ligipääs" "Kogukondade tugi veel puudub" "Kogukonna liikmed" "Selleks, et jututuba oleks nähtav jututubade avalikus kataloogis, vajab ta aadressi." - "Avaldatud aadress" + "Aadress" "Võimalda leida seda jututuba avalikust kataloogist otsides „%1$s“" "Luba leitavus avaliku kataloogi otsingust." "Nähtav avalikus kataloogis" @@ -148,7 +150,6 @@ Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega "Jututoa aadressid annavad võimaluse neid leida ning saada neile ligi. Samuti võimaldab see jututuba teistele huvilistele jagada. Lisaks võid sa jututoa avaldada oma koduserveri avalikus jututubade kataloogis." "Jututoa avaldamine" - "Jututoa aadressid annavad võimaluse neid leida ning saada neile ligi. Samuti võimaldab see jututuba teistele huvilistele jagada." - "Jututoa nähtavus" + "Nähtavus" "Turvalisus ja privaatsus" diff --git a/features/roomdetails/impl/src/main/res/values-eu/translations.xml b/features/roomdetails/impl/src/main/res/values-eu/translations.xml index 49e8eecec1..89a77bd4c8 100644 --- a/features/roomdetails/impl/src/main/res/values-eu/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-eu/translations.xml @@ -70,7 +70,6 @@ "Kendu debekua" "Debekatuta" "Kideak" - "Zain" "Administratzaileak soilik" "Administratzaileak eta moderatzaileak" "Jabea" diff --git a/features/roomdetails/impl/src/main/res/values-fa/translations.xml b/features/roomdetails/impl/src/main/res/values-fa/translations.xml index df048f7d22..3243eff70f 100644 --- a/features/roomdetails/impl/src/main/res/values-fa/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-fa/translations.xml @@ -76,7 +76,6 @@ "تحریم نکردن از اتاق" "محروم" "اعضا" - "منتظر" "فقط مدیران" "مدیرن و ناظران" "مالک" diff --git a/features/roomdetails/impl/src/main/res/values-fi/translations.xml b/features/roomdetails/impl/src/main/res/values-fi/translations.xml index c0ba6babb6..f1cf00453a 100644 --- a/features/roomdetails/impl/src/main/res/values-fi/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-fi/translations.xml @@ -80,7 +80,6 @@ "Poista porttikielto huoneesta" "Porttikiellot" "Jäsenet" - "Kutsuttu" "Vain ylläpitäjät" "Ylläpitäjät ja valvojat" "Omistaja" @@ -144,7 +143,6 @@ Emme suosittele salauksen ottamista käyttöön huoneissa, jotka kuka tahansa vo "Huoneosoitteet ovat tapoja löytää ja käyttää huoneita. Näin voit myös helposti jakaa huoneesi muiden kanssa. Voit halutessasi julkaista huoneesi kotipalvelimesi julkisessa huonehakemistossa." "Huoneen julkaiseminen" - "Huoneosoitteet ovat tapoja löytää ja käyttää huoneita. Näin voit myös helposti jakaa huoneesi muiden kanssa." "Huoneen näkyvyys" "Turvallisuus ja yksityisyys" diff --git a/features/roomdetails/impl/src/main/res/values-fr/translations.xml b/features/roomdetails/impl/src/main/res/values-fr/translations.xml index 53255299fe..4868d1413b 100644 --- a/features/roomdetails/impl/src/main/res/values-fr/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-fr/translations.xml @@ -82,7 +82,6 @@ "Débannir du salon" "Bannis" "Membres" - "En attente" "Administrateurs" "Modérateurs" "Propriétaire" @@ -148,7 +147,6 @@ Nous ne recommandons pas d’activer le chiffrement pour les salons que tout le "Les adresses de salon sont un moyen de trouver et d’accéder aux salons. Cela vous permet également de partager facilement votre salon avec d’autres personnes. Vous pouvez choisir de publier votre salon dans l’annuaire des salons publics de votre serveur d’accueil." "Publication du salon" - "Les adresses de salon sont un moyen de trouver et d’accéder aux salons. Cela vous permet également de partager facilement votre salon avec d’autres personnes." "Visibilité" "Sécurité & confidentialité" diff --git a/features/roomdetails/impl/src/main/res/values-hu/translations.xml b/features/roomdetails/impl/src/main/res/values-hu/translations.xml index dae2ed76d0..f105fc6262 100644 --- a/features/roomdetails/impl/src/main/res/values-hu/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-hu/translations.xml @@ -82,7 +82,7 @@ "Visszaengedés a szobába" "Kitiltva" "Tagok" - "Függőben" + "Függőben" "Adminisztrátor" "Moderátor" "Tulajdonos" @@ -118,8 +118,8 @@ "Szerepkörök" "Szoba részletei" "Szerepkörök és jogosultságok" - "Szobacím hozzáadása" - "Bárki kérhet hozzáférést, de a kérést egy adminisztrátornak kell jóváhagynia." + "Cím hozzáadása" + "Mindenkinek hozzáférést kell kérnie." "Csatlakozás kérése" "Igen, engedélyezze a titkosítást" "Az engedélyezés után a szoba titkosítása nem tiltható le. Az üzenetek előzményei csak a szobatagok számára láthatók, amikor meghívást kaptak, vagy mióta csatlakoztak a szobához. @@ -132,12 +132,12 @@ Nem javasoljuk a titkosítás engedélyezését az olyan szobákban, amelyeket b "Bárki csatlakozhat." "Bárki" "Csak a meghívott emberek léphetnek be." - "Privát" + "Csak meghívásos" "Hozzáférés" "A terek jelenleg nem támogatottak" "A tér tagjai" "Szüksége lesz egy szobacímre, hogy láthatóvá tegye a szobakatalógusban." - "Közzétett cím" + "Cím" "A szoba megtalálhatóvá tétele a(z) %1$s nyilvános szobakatalógusában való kereséssel." "Lehetővé teszi, hogy a nyilvános szobakatalógusban megtalálható legyen." "Látható a nyilvános szobakatalógusban" @@ -148,7 +148,6 @@ Nem javasoljuk a titkosítás engedélyezését az olyan szobákban, amelyeket b "A szobacímek a szobák megtalálásának és elérésnek módjai. Ez azt is biztosítja, hogy könnyen megoszthatja a szobáját másokkal. Kiválaszthatja, hogy szobáját közzéteszi-e a Matrix-kiszolgáló nyilvános szobakatalógusában." "Szoba közzététele" - "A szobacímek a szobák megtalálásának és elérésnek módjai. Ez azt is biztosítja, hogy könnyen megoszthatja a szobáját másokkal." - "Szoba láthatósága" + "Láthatóság" "Biztonság és adatvédelem" diff --git a/features/roomdetails/impl/src/main/res/values-in/translations.xml b/features/roomdetails/impl/src/main/res/values-in/translations.xml index fdba2e83f4..431c4e66f1 100644 --- a/features/roomdetails/impl/src/main/res/values-in/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-in/translations.xml @@ -73,7 +73,6 @@ "Batalkan cekalan dari ruangan" "Tercekal" "Anggota" - "Tertunda" "Hanya admin" "Admin dan moderator" "Anggota ruangan" @@ -132,6 +131,5 @@ Kami tidak menyarankan untuk mengaktifkan enkripsi untuk ruangan yang dapat dite "Hanya anggota sejak memilih opsi ini" "Alamat ruangan adalah cara untuk menemukan dan mengakses ruangan. Ini juga memastikan Anda dapat dengan mudah berbagi ruangan dengan orang lain. Anda dapat memilih untuk menerbitkan ruangan Anda di direktori ruangan publik homeserver Anda." "Penerbitan ruangan" - "Alamat ruangan adalah cara untuk menemukan dan mengakses ruangan. Hal ini juga memastikan Anda dapat dengan mudah berbagi ruangan dengan orang lain." "Keamanan & privasi" diff --git a/features/roomdetails/impl/src/main/res/values-it/translations.xml b/features/roomdetails/impl/src/main/res/values-it/translations.xml index 7a88d7b27b..1a315d8de0 100644 --- a/features/roomdetails/impl/src/main/res/values-it/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-it/translations.xml @@ -78,7 +78,6 @@ "Riammetti nella stanza" "Esclusi" "Membri" - "In attesa" "Solo amministratori" "Amministratori e moderatori" "Proprietario" @@ -142,7 +141,6 @@ Non consigliamo di attivare la crittografia per le stanze che chiunque può trov "Gli indirizzi delle stanze sono modi per trovare e accedervi. In questo modo puoi anche condividere facilmente la tua stanze con altri. Puoi scegliere di pubblicare la tua stanza nell\'elenco delle stanza pubbliche dell\'homeserver." "Pubblicazione della stanza" - "Gli indirizzi delle stanze sono modi per trovare e accedere a queste ultime. Questo assicura anche che tu possa condividere facilmente la tua stanza con altri." "Visibilità della stanza" "Sicurezza e privacy" diff --git a/features/roomdetails/impl/src/main/res/values-ka/translations.xml b/features/roomdetails/impl/src/main/res/values-ka/translations.xml index a18d194a1a..d9c56aa89c 100644 --- a/features/roomdetails/impl/src/main/res/values-ka/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ka/translations.xml @@ -63,7 +63,6 @@ "მოწვევის შემთხვევაში განბლოკილი მომხმარებელი ისევ შეძლებს ოთახს შეუერთდეს." "დაბლოკილები" "წევრები" - "მომლოდინე" "მხოლოდ ადმინისტრატორები" "ადმინისტრატორები და მოდერატორები" "ოთახის წევრები" diff --git a/features/roomdetails/impl/src/main/res/values-ko/translations.xml b/features/roomdetails/impl/src/main/res/values-ko/translations.xml index 7b7233ebcd..c025fdbf49 100644 --- a/features/roomdetails/impl/src/main/res/values-ko/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ko/translations.xml @@ -77,7 +77,6 @@ "방에서 차단 해제" "차단됨" "회원들" - "보류 중" "관리자 전용" "관리자 및 중재자" "소유자" @@ -140,6 +139,5 @@ "방 주소는 방을 찾고 액세스하는 방법입니다. 이를 통해 다른 사람들과 방을 쉽게 공유할 수 있습니다. 홈서버의 공개 방 디렉토리에 방을 공개할지 여부를 선택할 수 있습니다." "방 게시" - "방 주소는 방을 찾고 액세스하는 방법입니다. 또한 이 주소를 사용하면 다른 사람들과 방을 쉽게 공유할 수 있습니다." "보안 및 개인정보 보호" diff --git a/features/roomdetails/impl/src/main/res/values-lt/translations.xml b/features/roomdetails/impl/src/main/res/values-lt/translations.xml index e4f4ea4ece..727875d696 100644 --- a/features/roomdetails/impl/src/main/res/values-lt/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-lt/translations.xml @@ -20,6 +20,5 @@ "%1$d asmenys" "%1$d asmenų" - "Laukiama" "Kambario nariai" diff --git a/features/roomdetails/impl/src/main/res/values-nb/translations.xml b/features/roomdetails/impl/src/main/res/values-nb/translations.xml index 1d89958277..4fa2154462 100644 --- a/features/roomdetails/impl/src/main/res/values-nb/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-nb/translations.xml @@ -80,7 +80,6 @@ "Fjern utestengelsen fra rommet" "Utestengt" "Medlemmer" - "Venter" "Kun for administratorer" "Administratorer og moderatorer" "Eier" @@ -143,6 +142,5 @@ Vi anbefaler ikke å aktivere kryptering for rom som hvem som helst kan finne og "Romadresser er måter å finne og få tilgang til rom på. Dette sikrer også at du enkelt kan dele rommet ditt med andre. Du kan velge å publisere rommet ditt i hjemeserverens offentlige romkatalog." "Publisering av rom" - "Romadresser er en måte å finne og få tilgang til rommene på. Dette sikrer også at du enkelt kan dele rommet ditt med andre." "Sikkerhet og personvern" diff --git a/features/roomdetails/impl/src/main/res/values-nl/translations.xml b/features/roomdetails/impl/src/main/res/values-nl/translations.xml index c1c7096cf5..73e7b7f8c6 100644 --- a/features/roomdetails/impl/src/main/res/values-nl/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-nl/translations.xml @@ -68,7 +68,6 @@ "Ze kunnen opnieuw tot de kamer toetreden als ze worden uitgenodigd." "Verbannen" "Leden" - "In behandeling" "Alleen beheerders" "Beheerders en moderators" "Kamerleden" diff --git a/features/roomdetails/impl/src/main/res/values-pl/translations.xml b/features/roomdetails/impl/src/main/res/values-pl/translations.xml index c065da93a9..b7382e8d90 100644 --- a/features/roomdetails/impl/src/main/res/values-pl/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-pl/translations.xml @@ -81,7 +81,6 @@ "Odbanuj z pokoju" "Zbanowanych" "Członków" - "Oczekujące" "Tylko administratorzy" "Administratorzy i moderatorzy" "Właściciel" diff --git a/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml b/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml index 92fca8b192..4eb9da3062 100644 --- a/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml @@ -78,7 +78,6 @@ "Desbanir da sala" "Banidos" "Membros" - "Pendente" "Somente administradores" "Administradores e moderadores" "Proprietário" @@ -141,6 +140,5 @@ Não recomendamos que você ative a criptografia para salas que qualquer pessoa "Os endereços das salas são formas de encontrar e acessar as salas. Isso também garante que você possa compartilhar facilmente sua sala com outras pessoas. Você pode optar por publicar sua sala no diretório público de salas do seu servidor-casa." "Publicação da sala" - "Os endereços das salas são formas de encontrar e acessar as salas. Isso também garante que você possa compartilhar facilmente sua sala com outras pessoas." "Segurança e privacidade" diff --git a/features/roomdetails/impl/src/main/res/values-pt/translations.xml b/features/roomdetails/impl/src/main/res/values-pt/translations.xml index dc8b82a28f..7f9aca6ea1 100644 --- a/features/roomdetails/impl/src/main/res/values-pt/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-pt/translations.xml @@ -80,7 +80,6 @@ "Desbanir da sala" "Banidos" "Participantes" - "Pendente" "Apenas administradores" "Administradores e moderadores" "Dono / Dona" @@ -144,7 +143,6 @@ Não recomendamos ativar a cifragem em salas que qualquer pessoa possa encontrar "Estes endereços permitem encontrar e aceder a sala, bem como a sua fácil partilha com outros. Podes escolher publicar a sala no diretório público do teu servidor." "Publicar sala" - "Estes endereços permitem encontrar e aceder a sala, bem como a sua fácil partilha com outros." "Visibilidade da sala" "Segurança e privacidade" diff --git a/features/roomdetails/impl/src/main/res/values-ro/translations.xml b/features/roomdetails/impl/src/main/res/values-ro/translations.xml index 7dce932a3d..682f312c84 100644 --- a/features/roomdetails/impl/src/main/res/values-ro/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ro/translations.xml @@ -80,7 +80,6 @@ "Revocati excluderea din camera" "Excluși" "Membri" - "În așteptare" "Doar administratori" "Administratori și moderatori" "Proprietar" @@ -143,6 +142,5 @@ Nu recomandăm activarea criptării pentru camerele pe care oricine le poate gă "Adresele camerelor sunt modalități de a găsi și accesa camere. Acest lucru vă asigură, de asemenea, că puteți partaja cu ușurință camera dumneavoastră cu alte persoane. Puteți alege să publicați camera în directorul public al camerelor serverului dumneavoastră." "Publicare cameră" - "Adresele camerelor sunt modalități de a găsi și accesa camerele. Acest lucru vă asigură, de asemenea, că puteți partaja cu ușurință camera dvs. cu alte persoane." "Securitate & confidențialitate" diff --git a/features/roomdetails/impl/src/main/res/values-ru/translations.xml b/features/roomdetails/impl/src/main/res/values-ru/translations.xml index e3cdf7d851..324caed3dc 100644 --- a/features/roomdetails/impl/src/main/res/values-ru/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ru/translations.xml @@ -71,6 +71,8 @@ "Тема" "Обновление комнаты…" "В этой комнате нет заблокированных пользователей." + "Проверьте правописание или попробуйте новый поиск" + "Отсутствует результат по запросу “%1$s”" "%1$d пользователь" "%1$d пользователя" @@ -83,7 +85,7 @@ "Разблокировать в комнате" "Заблокированные" "Участники" - "В ожидании" + "В ожидании" "Только администраторы" "Модератор" "Владелец" @@ -119,8 +121,8 @@ "Роли" "Информация о комнате" "Роли и разрешения" - "Добавить адрес комнаты" - "Любой желающий может подать заявку на присоединение к комнате, но администратор должен будет принять запрос." + "Добавить адрес" + "Каждый должен запросить доступ." "Попросить присоединиться" "Да, включить шифрование" "Шифрование комнаты нельзя будет отключить, история сообщений будет видна только участникам комнаты с момента их приглашения или с момента присоединения к комнате. @@ -138,7 +140,7 @@ "Пространства в настоящее время не поддерживаются." "Участники пространства" "Вам понадобится адрес комнаты, чтобы сделать ее видимой в каталоге." - "Опубликованный адрес" + "Адрес" "Опубликовать %1$s в каталоге публичных комнат" "Разрешить поиск в публичном каталоге." "Доступна в списке публичных комнат" @@ -149,7 +151,6 @@ "Адреса комнат — это способ найти комнату и получить к ней доступ. Это также гарантирует, что вы сможете легко поделиться своей комнатой с другими. Вы можете опубликовать свою комнату в каталоге общедоступных комнат на домашнем сервере." "Публикация комнат" - "Адреса комнат — это способ найти комнату и получить к ним доступ. Это также гарантирует, что вы сможете легко поделиться своей комнатой с другими." - "Видимость комнаты" + "Видимость" "Безопасность и конфиденциальность" diff --git a/features/roomdetails/impl/src/main/res/values-sk/translations.xml b/features/roomdetails/impl/src/main/res/values-sk/translations.xml index ad79d94860..662a7c166a 100644 --- a/features/roomdetails/impl/src/main/res/values-sk/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-sk/translations.xml @@ -81,7 +81,6 @@ "Zrušiť zákaz prístupu do miestnosti" "Zakázaní" "Členovia" - "Čaká sa" "Iba správcovia" "Správcovia a moderátori" "Vlastník" @@ -145,7 +144,6 @@ To môže brániť správnemu fungovaniu robotov a premostení. Neodporúčame p "Adresy miestností predstavujú spôsoby, ako nájsť a získať prístup k miestnostiam. To tiež zaisťuje, že môžete jednoducho zdieľať svoju miestnosť s ostatnými. Môžete sa rozhodnúť zverejniť svoju miestnosť v adresári verejných miestností vášho domovského servera." "Zverejnenie miestnosti" - "Adresy miestností predstavujú spôsoby, ako nájsť a získať prístup k miestnostiam. Toto tiež zaisťuje, že môžete jednoducho zdieľať svoju miestnosť s ostatnými." "Viditeľnosť miestnosti" "Bezpečnosť a súkromie" diff --git a/features/roomdetails/impl/src/main/res/values-sv/translations.xml b/features/roomdetails/impl/src/main/res/values-sv/translations.xml index 353a586c00..8e2df0138e 100644 --- a/features/roomdetails/impl/src/main/res/values-sv/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-sv/translations.xml @@ -78,7 +78,6 @@ "Avbanna från rummet" "Bannade" "Medlemmar" - "Väntar" "Endast administratörer" "Administratörer och moderatorer" "Ägare" @@ -141,6 +140,5 @@ Vi rekommenderar inte att aktivera kryptering för rum som vem som helst kan hit "Rumsadresser är sätt att hitta och komma åt rum. Detta säkerställer också att du enkelt kan dela ditt rum med andra. Du kan välja att publicera ditt rum i din hemservers offentliga rumskatalog." "Rumspublicering" - "Rumsadresser är sätt att hitta och komma åt rum. Detta säkerställer också att du enkelt kan dela ditt rum med andra." "Säkerhet och sekretess" diff --git a/features/roomdetails/impl/src/main/res/values-tr/translations.xml b/features/roomdetails/impl/src/main/res/values-tr/translations.xml index 90a1a5b3c7..11201d0da0 100644 --- a/features/roomdetails/impl/src/main/res/values-tr/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-tr/translations.xml @@ -73,7 +73,6 @@ "Davet edildikleri takdirde bu odaya tekrar katılabileceklerdir." "Yasaklandı" "Üyeler" - "Beklemede" "Yalnızca yöneticiler" "Yöneticiler ve moderatörler" "Oda üyeleri" @@ -134,7 +133,6 @@ Herkesin bulabileceği ve katılabileceği odalar için şifrelemenin etkinleşt "Oda adresleri, odaları bulmanın ve odalara erişmenin yoludur. Bu aynı zamanda odanızı başkalarıyla kolayca paylaşabilmenizi sağlar. Odanızı ana sunucunuzun genel oda dizininde yayınlamayı seçebilirsiniz." "Oda yayınlama" - "Oda adresleri, odaları bulmanın ve odalara erişmenin yollarıdır. Bu aynı zamanda odanızı başkalarıyla kolayca paylaşabilmenizi sağlar." "Oda görünürlüğü" "Güvenlik ve gizlilik" diff --git a/features/roomdetails/impl/src/main/res/values-uk/translations.xml b/features/roomdetails/impl/src/main/res/values-uk/translations.xml index f8ab7a1ced..34663f9db9 100644 --- a/features/roomdetails/impl/src/main/res/values-uk/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-uk/translations.xml @@ -79,7 +79,6 @@ "Розблокувати в кімнаті" "Заблоковані" "Учасники" - "На розгляді" "Тільки для адміністраторів" "Адміністратори та модератори" "Власник" @@ -143,7 +142,6 @@ "Адреси кімнат — це спосіб знайти кімнату та отримати до неї доступ. Це також гарантує, що ви можете легко поділитися своєю кімнатою з іншими. Ви можете опублікувати свою кімнату в каталозі загальнодоступних кімнат вашого домашнього сервера." "Публікація в кімнаті" - "Адреси кімнат — це спосіб знайти та отримати доступ до кімнат. Це також гарантує, що ви зможете легко поділитися своєю кімнатою з іншими." "Видимість кімнати" "Безпека й приватність" diff --git a/features/roomdetails/impl/src/main/res/values-ur/translations.xml b/features/roomdetails/impl/src/main/res/values-ur/translations.xml index 5f6eb34bca..524afe515d 100644 --- a/features/roomdetails/impl/src/main/res/values-ur/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ur/translations.xml @@ -68,7 +68,6 @@ "اگر وہ مدعو کیا جائیں تو وہ دوبارہ اس کمرے میں شامل ہوسکیں گے۔" "محظور" "اراکین" - "زیر التواء" "صرف منتظمین" "منتظمین اور ناظمین" "کمرے کے ارکان" diff --git a/features/roomdetails/impl/src/main/res/values-uz/translations.xml b/features/roomdetails/impl/src/main/res/values-uz/translations.xml index f4a4d891ce..a95af68769 100644 --- a/features/roomdetails/impl/src/main/res/values-uz/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-uz/translations.xml @@ -68,7 +68,6 @@ "Agar taklif qilinsa, ular bu xonaga qayta qo‘shilishlari mumkin." "Taqiqlangan" "Azolar" - "Kutilmoqda" "Faqat adminlar" "Adminlar va moderatorlar" "Xona a\'zolari" diff --git a/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml b/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml index 83b71a81fe..9de710e576 100644 --- a/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml @@ -1,19 +1,21 @@ - "您需要聊天室地址才能在目錄中顯示它。" - "聊天室地址" + "您需要地址才能在公開目錄中顯示。" + "編輯地址" "更新通知設定時發生錯誤。" "您的家伺服器在加密聊天室中不支援此選項,可能無法收到部份聊天室的通知。" "所有投票" - "僅限管理員" + "管理員" "管理黑名單" "移除訊息" - "邀請夥伴並接受加入請求" + "成員" + "邀請夥伴" + "管理成員" "訊息與內容" - "管理員和版主" - "移除夥伴並拒絕加入請求" + "版主" + "移除夥伴" "變更聊天室大頭照" - "編輯聊天室" + "編輯詳細資訊" "變更聊天室名稱" "變更聊天室主題" "傳送訊息" @@ -40,7 +42,7 @@ "已加密" "未加密" "公開的聊天室" - "編輯聊天室" + "編輯詳細資訊" "發生未知錯誤,無法變更資訊。" "無法更新聊天室" "訊息透過鎖定保護。只有您與收件者才有解鎖它們的唯一金鑰。" @@ -60,7 +62,7 @@ "釘選訊息" "個人檔案" "請求加入" - "身份與權限" + "角色與權限" "聊天室名稱" "安全與隱私" "安全性" @@ -69,8 +71,10 @@ "主題" "正在更新聊天室…" "沒有被封鎖的使用者。" + "檢查拼字或嘗試新搜尋" + "找不到「%1$s」" - "%1$d 位夥伴" + "%1$d 個人" "踢出並加入黑名單" "僅移除成員" @@ -79,9 +83,9 @@ "從聊天室解除封鎖" "黑名單" "成員" - "待定" - "僅限管理員" - "管理員和版主" + "擱置中" + "管理員" + "版主" "擁有者" "聊天室成員" "正在解除黑名單 %1$s" @@ -108,14 +112,15 @@ "訊息與內容" "版主" "擁有者" + "權限" "重設權限" "重設之後,您會遺失當前的設定。" "確定要重設權限嗎?" "身份" "聊天室資訊" - "身份與權限" - "新增聊天室地址" - "任何人都可以要求加入聊天室,但管理員必須接受請求。" + "角色與權限" + "新增地址" + "所有人都必須申請存取權。" "要求加入" "是的,啟用加密" "啟用後就無法停用聊天室的加密,只有受邀的聊天室成員或加入聊天室後才能看到訊息歷史紀錄。 @@ -125,17 +130,18 @@ "一旦啟用就無法停用加密。" "加密" "啟用端到端加密" - "任何人都可以找到並加入" + "任何人都可以加入。" "任何人" - "人們僅有受到邀請時才能加入" + "僅受邀者才能加入。" "僅限邀請" - "聊天室存取權" + "存取權" "目前不支援空間" "空間成員" - "您需要聊天室地址才能在目錄中顯示它。" - "聊天室地址" + "您需要地址才能在公開目錄中顯示。" + "地址" "允許透過搜尋 %1$s 公開聊天室目錄找到此聊天室" - "在公開聊天室目錄中可見" + "允許其他人透過公開目錄找到。" + "在公開目錄中可見" "任何人" "誰可以讀取歷史紀錄" "僅在成員被邀請後" @@ -143,7 +149,6 @@ "聊天室地址是尋找與存取聊天室的方法。也確保您可以輕鬆與其他人分享聊天室。 您可以選擇在家伺服器公開聊天室目錄中發佈您的聊天室。" "聊天室發佈" - "聊天室地址是尋找與存取聊天室的方法。也確保您可以輕鬆與其他人分享聊天室。" - "聊天室能見度" + "能見度" "安全與隱私" diff --git a/features/roomdetails/impl/src/main/res/values-zh/translations.xml b/features/roomdetails/impl/src/main/res/values-zh/translations.xml index f504744964..a373e5d3c4 100644 --- a/features/roomdetails/impl/src/main/res/values-zh/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-zh/translations.xml @@ -79,7 +79,6 @@ "从房间取消解封" "已封禁用户" "成员" - "待处理" "仅限管理员" "管理员和协管员" "所有者" @@ -143,7 +142,6 @@ "房间地址是查找和访问房间的方式。这也确保你可以轻松地向他人分享房间。 你可以选择在你服务器的公共房间目录中发布你的房间。" "房间发布" - "房间地址是查找和访问房间的方式。这也确保你可以轻松地向他人分享房间。" "房间可见性" "安全与隐私" diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index 2f9f2de9b7..2f57c250f1 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -71,9 +71,15 @@ "Topic" "Updating room…" "There are no banned users." + + "%1$d Banned" + "%1$d Banned" + + "Check the spelling or try a new search" + "No results for “%1$s”" - "%1$d person" - "%1$d people" + "%1$d Person" + "%1$d People" "Ban user" "Only remove member" @@ -82,7 +88,11 @@ "Unban user" "Banned" "Members" - "Pending" + + "%1$d Invited" + "%1$d Invited" + + "Pending" "Admin" "Moderator" "Owner" @@ -148,7 +158,7 @@ We do not recommend enabling encryption for rooms that anyone can find and join. "Room addresses are ways to find and access rooms. This also ensures you can easily share your room with others. You can choose to publish your room in your homeserver public room directory." "Room publishing" - "Addresses are a way to find and access rooms. This also ensures you can easily share your room with others." + "Addresses are a way to find and access rooms and spaces. This also ensures you can easily share them with others." "Visibility" "Security & privacy" diff --git a/features/roommembermoderation/impl/src/main/res/values-zh-rTW/translations.xml b/features/roommembermoderation/impl/src/main/res/values-zh-rTW/translations.xml index de8a9712ee..14a044a7dc 100644 --- a/features/roommembermoderation/impl/src/main/res/values-zh-rTW/translations.xml +++ b/features/roommembermoderation/impl/src/main/res/values-zh-rTW/translations.xml @@ -4,12 +4,14 @@ "加入黑名單" "即使收到邀請,他們仍然無法加入聊天室。" "您確定要將此成員加入黑名單?" + "即使被邀請,他們也無法再次加入此空間,但他們仍將保留其在任何聊天室或子空間的成員資格。" "正在將 %1$s 加入黑名單" "移除" "如果收到邀請,他們能再次加入聊天室。" "您真的想要移除此成員嗎?" + "若受邀,他們將可以再次加入此空間,並保留所有聊天室與子空間的成員資格。" "查看個人檔案" - "踢出聊天室" + "移除使用者" "移除成員並禁止未來再度加入?" "正在踢出 %1$s…" "從聊天室解除封鎖" diff --git a/features/space/impl/src/main/res/values-zh-rTW/translations.xml b/features/space/impl/src/main/res/values-zh-rTW/translations.xml index 977024c5cf..abf495860f 100644 --- a/features/space/impl/src/main/res/values-zh-rTW/translations.xml +++ b/features/space/impl/src/main/res/values-zh-rTW/translations.xml @@ -10,6 +10,6 @@ "離開 %1$s?" "您是 %1$s 唯一的管理員" "離開空間" - "身份與權限" + "角色與權限" "安全與隱私" diff --git a/features/verifysession/impl/src/main/res/values-bg/translations.xml b/features/verifysession/impl/src/main/res/values-bg/translations.xml index 1a2e194696..357600cf60 100644 --- a/features/verifysession/impl/src/main/res/values-bg/translations.xml +++ b/features/verifysession/impl/src/main/res/values-bg/translations.xml @@ -10,6 +10,9 @@ "Нещо не изглежда наред. Или времето за изчакване на заявката е изтекло, или заявката е отхвърлена." "Потвърдете, че емоджитата по-долу съвпадат с показаните в другото ви устройство." "Сравнете емоджита" + "Уверете се, че емоджитата по-долу съвпадат с показаните на другото устройство." + "Уверете се, че числата по-долу съвпадат с показаните на другата ви сесия." + "Сравнете числа" "Сега можете да четете или изпращате съобщения сигурно на другото си устройство." "Устройството е потвърдено" "Въвеждане на ключ за възстановяване" @@ -20,13 +23,17 @@ "В очакване на съвпадение" "Сравнете уникален набор от емоджита." "Сравнете уникалните емоджита, като се уверите, че се появяват в същия ред." + "Влезли" "Неуспешно потвърждаване" + "Продължете само ако вие сте инициирали това потвърждаване." "Сега можете да четете или изпращате съобщения сигурно на другото си устройство." "Устройството е потвърдено" + "Поискано е потвърждение" "Те не съвпадат" "Те съвпадат" "Уверете се, че приложението е отворено на другото устройство, преди да започнете потвърждението оттук." "Отворете приложението на друго потвърдено устройство" + "Потвърждаване на този потребител?" "Чака се другият потребител" "След като бъдете приети, ще можете да продължите потвърждението." "Приемете заявката, за да започнете процеса на потвърждаване в другата си сесия, за да продължите." diff --git a/libraries/push/impl/src/main/res/values-zh-rTW/translations.xml b/libraries/push/impl/src/main/res/values-zh-rTW/translations.xml index 9e167a2e92..f0c1f1046f 100644 --- a/libraries/push/impl/src/main/res/values-zh-rTW/translations.xml +++ b/libraries/push/impl/src/main/res/values-zh-rTW/translations.xml @@ -11,6 +11,7 @@ "%d 個通知" + "Unified Push 通知散佈程式註冊失敗,因此您無法再收到通知。請檢查應用程式的通知設定與推播散佈程式的狀態。" "您有新訊息。" "📹 來電" "** 無法傳送,請開啟聊天室" diff --git a/libraries/ui-strings/src/main/res/values-bg/translations.xml b/libraries/ui-strings/src/main/res/values-bg/translations.xml index da290cbec5..5265110a65 100644 --- a/libraries/ui-strings/src/main/res/values-bg/translations.xml +++ b/libraries/ui-strings/src/main/res/values-bg/translations.xml @@ -130,7 +130,9 @@ "Относно" "Политика за приемлива употреба" "Добавяне на акаунт" + "Добавяне на друг акаунт" "Разширени настройки" + "изображение" "Статистика" "Напуснахте стаята" "Облик" @@ -142,6 +144,7 @@ "Авторски права" "Създаване на стая…" "Стаята е напусната" + "Пространството е напуснато" "Тъмен" "Грешка при разшифроване" "Описание" @@ -172,6 +175,7 @@ "Инсталиране на APK" "Този Matrix ID не може да бъде намерен, така че поканата може да не бъде получена." "Стаята се напуска" + "Пространството се напуска" "Светъл" "Връзката е копирана в клипборда" "Зарежда се…" @@ -214,6 +218,7 @@ "Подготвя се…" "Политика за поверителност" "Частна стая" + "Частно пространство" "Общодостъпна стая" "Общодостъпно пространство" "Реакция" @@ -243,15 +248,19 @@ "Резултати от търсенето" "Защита" "Видяно от" + "Избиране на акаунт" "Изпраща се…" "Изпращането е неуспешно" "Изпратено" "Сървърът не се поддържа" "URL адрес на сървъра" "Настройки" + "Споделяне на пространството" "Споделено местоположение" "Излизате" + "Нещо се обърка" "Възникна проблем. Моля, опитайте отново." + "Пространство" "%1$d пространство" "%1$d пространства" @@ -268,6 +277,7 @@ "Тема" "За какво се отнася тази стая?" "Не може да се разшифрова" + "Нямате достъп до това съобщение" "Поканите не можаха да бъдат изпратени до един или повече потребители." "Не може да се изпрати покана(и)" "Отключване" @@ -282,6 +292,9 @@ "Потвърждаване на самоличността" "Потвърждаване на потребителя" "Видео" + "Високо качество" + "Ниско качество" + "Стандартно качество" "Гласово съобщение" "Изчаква се…" "В очакване на това съобщение" @@ -320,9 +333,11 @@ "Споделяне на това местоположение" "%1$s пространство" "Пространства" + "Преглед на членовете" "Местоположение" "Версия: %1$s (%2$s)" "bg" "Трябва да потвърдите това устройство за да достъпите исторически съобщения" + "Нямате достъп до това съобщение" "Съобщението не може да се разшифрова" diff --git a/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml b/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml index 0a8f32a694..1c88ac71df 100644 --- a/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml +++ b/libraries/ui-strings/src/main/res/values-zh-rTW/translations.xml @@ -93,6 +93,7 @@ "忘記密碼?" "轉寄" "返回" + "前往角色與權限" "前往設定" "忽略" "邀請" @@ -435,6 +436,10 @@ "未傳送您的訊息,因為 %1$s 尚未驗證所有裝置。" "您的一個或多個裝置未經驗證。您仍可傳送訊息,也可以取消並在您驗證您的所有裝置後再試一次。" "因為您尚未驗證一個或多個裝置,因為未傳送您的訊息" + "變更設定" + "管理空間" + "管理聊天室" + "權限" "編輯管理員或擁有者" "無法處理要上傳的媒體,請再試一次。" "無法擷取使用者詳細資訊" diff --git a/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_de.png b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_de.png new file mode 100644 index 0000000000..747cad00c9 --- /dev/null +++ b/screenshots/de/features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_de.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:640f53a7cac7a3b6693d462bb86a50db212d749a8603e8edaeed6c874ae573ba +size 66148 diff --git a/screenshots/html/data.js b/screenshots/html/data.js index 1626eec982..6d8ee5fbab 100644 --- a/screenshots/html/data.js +++ b/screenshots/html/data.js @@ -1,80 +1,80 @@ // Generated file, do not edit export const screenshots = [ ["en","en-dark","de",], -["features.preferences.impl.about_AboutView_Day_0_en","features.preferences.impl.about_AboutView_Night_0_en",20412,], +["features.preferences.impl.about_AboutView_Day_0_en","features.preferences.impl.about_AboutView_Night_0_en",20413,], ["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_0_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_0_en",0,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_1_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_1_en",20412,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20412,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20412,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20412,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20412,], -["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20412,], -["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20412,], -["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20412,], -["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20412,], -["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20412,], -["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20412,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_1_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_1_en",20413,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20413,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20413,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20413,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20413,], +["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20413,], +["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20413,], +["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20413,], +["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20413,], +["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20413,], +["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20413,], ["features.login.impl.accountprovider_AccountProviderView_Day_0_en","features.login.impl.accountprovider_AccountProviderView_Night_0_en",0,], ["features.login.impl.accountprovider_AccountProviderView_Day_1_en","features.login.impl.accountprovider_AccountProviderView_Night_1_en",0,], ["features.login.impl.accountprovider_AccountProviderView_Day_2_en","features.login.impl.accountprovider_AccountProviderView_Night_2_en",0,], ["features.login.impl.accountprovider_AccountProviderView_Day_3_en","features.login.impl.accountprovider_AccountProviderView_Night_3_en",0,], -["libraries.accountselect.impl_AccountSelectView_Day_0_en","libraries.accountselect.impl_AccountSelectView_Night_0_en",20412,], -["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20412,], +["libraries.accountselect.impl_AccountSelectView_Day_0_en","libraries.accountselect.impl_AccountSelectView_Night_0_en",20413,], +["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20413,], ["features.messages.impl.actionlist_ActionListViewContent_Day_0_en","features.messages.impl.actionlist_ActionListViewContent_Night_0_en",0,], -["features.messages.impl.actionlist_ActionListViewContent_Day_10_en","features.messages.impl.actionlist_ActionListViewContent_Night_10_en",20412,], -["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20412,], -["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20412,], +["features.messages.impl.actionlist_ActionListViewContent_Day_10_en","features.messages.impl.actionlist_ActionListViewContent_Night_10_en",20413,], +["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20413,], +["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20413,], ["features.messages.impl.actionlist_ActionListViewContent_Day_1_en","features.messages.impl.actionlist_ActionListViewContent_Night_1_en",0,], -["features.messages.impl.actionlist_ActionListViewContent_Day_2_en","features.messages.impl.actionlist_ActionListViewContent_Night_2_en",20412,], -["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20412,], -["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20412,], -["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20412,], -["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20412,], -["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20412,], -["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20412,], -["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20412,], -["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20412,], -["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20412,], -["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20412,], -["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20412,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20412,], -["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20412,], -["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20412,], +["features.messages.impl.actionlist_ActionListViewContent_Day_2_en","features.messages.impl.actionlist_ActionListViewContent_Night_2_en",20413,], +["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20413,], +["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20413,], +["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20413,], +["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20413,], +["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20413,], +["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20413,], +["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20413,], +["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20413,], +["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20413,], +["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20413,], +["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20413,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20413,], +["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20413,], +["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20413,], ["libraries.designsystem.theme.components_AllIcons_Icons_en","",0,], -["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20412,], -["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20412,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20412,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20412,], -["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20412,], +["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20413,], +["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20413,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20413,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20413,], +["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20413,], ["libraries.designsystem.components_Announcement_Day_0_en","libraries.designsystem.components_Announcement_Night_0_en",0,], -["services.apperror.impl_AppErrorView_Day_0_en","services.apperror.impl_AppErrorView_Night_0_en",20412,], +["services.apperror.impl_AppErrorView_Day_0_en","services.apperror.impl_AppErrorView_Night_0_en",20413,], ["libraries.designsystem.components.async_AsyncActionView_Day_0_en","libraries.designsystem.components.async_AsyncActionView_Night_0_en",0,], -["libraries.designsystem.components.async_AsyncActionView_Day_1_en","libraries.designsystem.components.async_AsyncActionView_Night_1_en",20412,], +["libraries.designsystem.components.async_AsyncActionView_Day_1_en","libraries.designsystem.components.async_AsyncActionView_Night_1_en",20413,], ["libraries.designsystem.components.async_AsyncActionView_Day_2_en","libraries.designsystem.components.async_AsyncActionView_Night_2_en",0,], -["libraries.designsystem.components.async_AsyncActionView_Day_3_en","libraries.designsystem.components.async_AsyncActionView_Night_3_en",20412,], +["libraries.designsystem.components.async_AsyncActionView_Day_3_en","libraries.designsystem.components.async_AsyncActionView_Night_3_en",20413,], ["libraries.designsystem.components.async_AsyncActionView_Day_4_en","libraries.designsystem.components.async_AsyncActionView_Night_4_en",0,], -["libraries.designsystem.components.async_AsyncFailure_Day_0_en","libraries.designsystem.components.async_AsyncFailure_Night_0_en",20412,], +["libraries.designsystem.components.async_AsyncFailure_Day_0_en","libraries.designsystem.components.async_AsyncFailure_Night_0_en",20413,], ["libraries.designsystem.components.async_AsyncIndicatorFailure_Day_0_en","libraries.designsystem.components.async_AsyncIndicatorFailure_Night_0_en",0,], ["libraries.designsystem.components.async_AsyncIndicatorLoading_Day_0_en","libraries.designsystem.components.async_AsyncIndicatorLoading_Night_0_en",0,], ["libraries.designsystem.components.async_AsyncLoading_Day_0_en","libraries.designsystem.components.async_AsyncLoading_Night_0_en",0,], -["features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en","features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en",20412,], +["features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en","features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en",20413,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_0_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_0_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_1_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_1_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_2_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_2_en",0,], @@ -84,19 +84,19 @@ export const screenshots = [ ["libraries.matrix.ui.components_AttachmentThumbnail_Day_6_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_6_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_7_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_7_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_8_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_8_en",0,], -["features.messages.impl.attachments.preview_AttachmentsView_0_en","",20412,], -["features.messages.impl.attachments.preview_AttachmentsView_1_en","",20412,], -["features.messages.impl.attachments.preview_AttachmentsView_2_en","",20412,], -["features.messages.impl.attachments.preview_AttachmentsView_3_en","",20412,], -["features.messages.impl.attachments.preview_AttachmentsView_4_en","",20412,], -["features.messages.impl.attachments.preview_AttachmentsView_5_en","",20412,], -["features.messages.impl.attachments.preview_AttachmentsView_6_en","",20412,], -["features.messages.impl.attachments.preview_AttachmentsView_7_en","",20412,], -["features.messages.impl.attachments.preview_AttachmentsView_8_en","",20412,], +["features.messages.impl.attachments.preview_AttachmentsView_0_en","",20413,], +["features.messages.impl.attachments.preview_AttachmentsView_1_en","",20413,], +["features.messages.impl.attachments.preview_AttachmentsView_2_en","",20413,], +["features.messages.impl.attachments.preview_AttachmentsView_3_en","",20413,], +["features.messages.impl.attachments.preview_AttachmentsView_4_en","",20413,], +["features.messages.impl.attachments.preview_AttachmentsView_5_en","",20413,], +["features.messages.impl.attachments.preview_AttachmentsView_6_en","",20413,], +["features.messages.impl.attachments.preview_AttachmentsView_7_en","",20413,], +["features.messages.impl.attachments.preview_AttachmentsView_8_en","",20413,], ["libraries.mediaviewer.impl.gallery.ui_AudioItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_AudioItemView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_AudioItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_AudioItemView_Night_1_en",0,], ["libraries.mediaviewer.impl.gallery.ui_AudioItemView_Day_2_en","libraries.mediaviewer.impl.gallery.ui_AudioItemView_Night_2_en",0,], -["libraries.matrix.ui.components_AvatarActionBottomSheet_Day_0_en","libraries.matrix.ui.components_AvatarActionBottomSheet_Night_0_en",20412,], +["libraries.matrix.ui.components_AvatarActionBottomSheet_Day_0_en","libraries.matrix.ui.components_AvatarActionBottomSheet_Night_0_en",20413,], ["libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en","",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_0_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_0_en",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_1_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_1_en",0,], @@ -123,22 +123,22 @@ export const screenshots = [ ["libraries.designsystem.modifiers_BackgroundVerticalGradientDisabled_Day_0_en","libraries.designsystem.modifiers_BackgroundVerticalGradientDisabled_Night_0_en",0,], ["libraries.designsystem.modifiers_BackgroundVerticalGradient_Day_0_en","libraries.designsystem.modifiers_BackgroundVerticalGradient_Night_0_en",0,], ["libraries.designsystem.components_Badge_Day_0_en","libraries.designsystem.components_Badge_Night_0_en",0,], -["features.home.impl.components_BatteryOptimizationBanner_Day_0_en","features.home.impl.components_BatteryOptimizationBanner_Night_0_en",20412,], +["features.home.impl.components_BatteryOptimizationBanner_Day_0_en","features.home.impl.components_BatteryOptimizationBanner_Night_0_en",20413,], ["libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en","libraries.designsystem.atomic.atoms_BetaLabel_Night_0_en",0,], ["libraries.designsystem.components_BigIcon_Day_0_en","libraries.designsystem.components_BigIcon_Night_0_en",0,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en",20412,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20412,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20412,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20412,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20412,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20412,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20412,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en",20413,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20413,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20413,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20413,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20413,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20413,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20413,], ["libraries.designsystem.theme.components_BottomSheetDragHandle_Day_0_en","libraries.designsystem.theme.components_BottomSheetDragHandle_Night_0_en",0,], -["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20412,], -["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20412,], -["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20412,], -["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20412,], -["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20412,], +["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20413,], +["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20413,], +["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20413,], +["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20413,], +["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20413,], ["features.rageshake.impl.bugreport_BugReportViewNight_0_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_1_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_2_en","",0,], @@ -148,132 +148,133 @@ export const screenshots = [ ["libraries.designsystem.atomic.molecules_ButtonRowMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ButtonRowMolecule_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_0_en","features.messages.impl.timeline.components_CallMenuItem_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_1_en","features.messages.impl.timeline.components_CallMenuItem_Night_1_en",0,], -["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20412,], -["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20412,], +["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20413,], +["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20413,], ["features.messages.impl.timeline.components_CallMenuItem_Day_4_en","features.messages.impl.timeline.components_CallMenuItem_Night_4_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_5_en","features.messages.impl.timeline.components_CallMenuItem_Night_5_en",0,], ["features.call.impl.ui_CallScreenView_Day_0_en","features.call.impl.ui_CallScreenView_Night_0_en",0,], -["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20412,], -["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20412,], -["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20412,], -["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20412,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20412,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20412,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20412,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20412,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20412,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20412,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20412,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20412,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20412,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20412,], +["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20413,], +["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20413,], +["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20413,], +["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20413,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20413,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20413,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20413,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20413,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20413,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20413,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20416,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20413,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20413,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20413,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20413,], ["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_5_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_5_en",0,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en",20412,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20412,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20412,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20412,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20412,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20412,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20412,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20412,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20412,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en",20413,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20413,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20413,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20413,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20413,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20413,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20413,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20413,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20413,], ["features.login.impl.changeserver_ChangeServerView_Day_0_en","features.login.impl.changeserver_ChangeServerView_Night_0_en",0,], -["features.login.impl.changeserver_ChangeServerView_Day_1_en","features.login.impl.changeserver_ChangeServerView_Night_1_en",20412,], -["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20412,], -["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20412,], -["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20412,], -["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20412,], +["features.login.impl.changeserver_ChangeServerView_Day_1_en","features.login.impl.changeserver_ChangeServerView_Night_1_en",20413,], +["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20413,], +["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20413,], +["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20413,], +["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20413,], ["libraries.matrix.ui.components_CheckableResolvedUserRow_en","",0,], -["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20412,], +["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20413,], ["libraries.designsystem.theme.components_Checkboxes_Toggles_en","",0,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_0_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_0_en",20412,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20412,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20412,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20412,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20412,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20412,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20412,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20412,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_0_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_0_en",20413,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20413,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20413,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20413,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20413,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20413,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20413,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20413,], ["libraries.designsystem.theme.components_CircularProgressIndicator_Progress_Indicators_en","",0,], ["libraries.designsystem.components_ClickableLinkText_Text_en","",0,], ["libraries.designsystem.theme_ColorAliases_Day_0_en","libraries.designsystem.theme_ColorAliases_Night_0_en",0,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_0_en",20412,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20412,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20412,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20412,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20412,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20412,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20412,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20412,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20412,], -["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20412,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_0_en",20413,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20413,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20413,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20413,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20413,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20413,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20413,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20413,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20413,], +["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20413,], ["libraries.textcomposer_ComposerModeView_Day_1_en","libraries.textcomposer_ComposerModeView_Night_1_en",0,], ["libraries.textcomposer_ComposerModeView_Day_2_en","libraries.textcomposer_ComposerModeView_Night_2_en",0,], ["libraries.textcomposer_ComposerModeView_Day_3_en","libraries.textcomposer_ComposerModeView_Night_3_en",0,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en","",20412,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20412,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20412,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20412,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20412,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20412,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20412,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20412,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20412,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20412,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20412,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20412,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20412,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20412,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20412,], -["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20412,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en","",20413,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20413,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20413,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20413,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20413,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20413,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20413,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20413,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20413,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20413,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20413,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20413,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20413,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20413,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20413,], +["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20413,], ["libraries.designsystem.components.dialogs_ConfirmationDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_ConfirmationDialog_Day_0_en","libraries.designsystem.components.dialogs_ConfirmationDialog_Night_0_en",0,], ["features.networkmonitor.api.ui_ConnectivityIndicator_Day_0_en","features.networkmonitor.api.ui_ConnectivityIndicator_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_CounterAtom_Day_0_en","libraries.designsystem.atomic.atoms_CounterAtom_Night_0_en",0,], -["features.rageshake.api.crash_CrashDetectionView_Day_0_en","features.rageshake.api.crash_CrashDetectionView_Night_0_en",20412,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20412,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20412,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20412,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20412,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20412,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20412,], -["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20412,], -["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20412,], -["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20412,], -["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20412,], -["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20412,], -["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20412,], -["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20412,], -["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20412,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20412,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20412,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20412,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20412,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20412,], +["features.rageshake.api.crash_CrashDetectionView_Day_0_en","features.rageshake.api.crash_CrashDetectionView_Night_0_en",20413,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20413,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20413,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20413,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20413,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20413,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20413,], +["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20413,], +["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20413,], +["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20413,], +["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20413,], +["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20413,], +["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20413,], +["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20413,], +["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20413,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20413,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20413,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20413,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20413,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20413,], ["libraries.mediaviewer.impl.gallery.ui_DateItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_DateItemView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_DateItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_DateItemView_Night_1_en",0,], -["libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_en","",20412,], -["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20412,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20412,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20412,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20412,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20412,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20412,], +["libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_en","",20413,], +["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20413,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20413,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20413,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20413,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20413,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20413,], ["features.logout.impl.direct_DefaultDirectLogoutView_Day_0_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_0_en",0,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_1_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_1_en",20412,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20412,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20412,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_1_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_1_en",20413,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20413,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20413,], ["features.logout.impl.direct_DefaultDirectLogoutView_Day_4_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_4_en",0,], -["features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Day_0_en","features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Night_0_en",20412,], +["features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Day_0_en","features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Night_0_en",20413,], ["features.licenses.impl.details_DependenciesDetailsView_Day_0_en","features.licenses.impl.details_DependenciesDetailsView_Night_0_en",0,], -["features.licenses.impl.list_DependencyLicensesListView_Day_0_en","features.licenses.impl.list_DependencyLicensesListView_Night_0_en",20412,], -["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20412,], -["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20412,], -["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20412,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20412,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20412,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20412,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20412,], +["features.licenses.impl.list_DependencyLicensesListView_Day_0_en","features.licenses.impl.list_DependencyLicensesListView_Night_0_en",20413,], +["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20413,], +["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20413,], +["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20413,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20413,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20413,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20413,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20413,], ["libraries.designsystem.theme.components_DialogWithDestructiveButton_Dialog_with_destructive_button_Dialogs_en","",0,], ["libraries.designsystem.theme.components_DialogWithOnlyMessageAndOkButton_Dialog_with_only_message_and_ok_button_Dialogs_en","",0,], ["libraries.designsystem.theme.components_DialogWithThirdButton_Dialog_with_third_button_Dialogs_en","",0,], @@ -288,18 +289,18 @@ export const screenshots = [ ["libraries.designsystem.text_DpScale_1_0f__en","",0,], ["libraries.designsystem.text_DpScale_1_5f__en","",0,], ["libraries.designsystem.theme.components_DropdownMenuItem_Menus_en","",0,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_0_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_0_en",20412,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20412,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20412,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20412,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20412,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_0_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_0_en",20412,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_1_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_1_en",20412,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_2_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_2_en",20412,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_3_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_3_en",20412,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_4_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_4_en",20412,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20412,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20412,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_0_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_0_en",20413,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20413,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20413,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20413,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20413,], +["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_0_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_0_en",20413,], +["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_1_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_1_en",20413,], +["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_2_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_2_en",20413,], +["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_3_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_3_en",20413,], +["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_4_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_4_en",20413,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20413,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20413,], ["libraries.matrix.ui.components_EditableAvatarView_Day_0_en","libraries.matrix.ui.components_EditableAvatarView_Night_0_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_1_en","libraries.matrix.ui.components_EditableAvatarView_Night_1_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_2_en","libraries.matrix.ui.components_EditableAvatarView_Night_2_en",0,], @@ -310,14 +311,14 @@ export const screenshots = [ ["libraries.designsystem.atomic.atoms_ElementLogoAtomMediumNoBlurShadow_Day_0_en","libraries.designsystem.atomic.atoms_ElementLogoAtomMediumNoBlurShadow_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_ElementLogoAtomMedium_Day_0_en","libraries.designsystem.atomic.atoms_ElementLogoAtomMedium_Night_0_en",0,], ["features.messages.impl.timeline.components.customreaction_EmojiItem_Day_0_en","features.messages.impl.timeline.components.customreaction_EmojiItem_Night_0_en",0,], -["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en",20412,], -["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20412,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en",20413,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20413,], ["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_2_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_2_en",0,], ["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_3_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_3_en",0,], ["libraries.ui.common.nodes_EmptyView_Day_0_en","libraries.ui.common.nodes_EmptyView_Night_0_en",0,], -["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20412,], -["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20412,], -["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20412,], +["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20413,], +["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20413,], +["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20413,], ["features.messages.impl.timeline.debug_EventDebugInfoView_Day_0_en","features.messages.impl.timeline.debug_EventDebugInfoView_Night_0_en",0,], ["libraries.designsystem.components_ExpandableBottomSheetLayout_en","",0,], ["libraries.featureflag.ui_FeatureListView_Day_0_en","libraries.featureflag.ui_FeatureListView_Night_0_en",0,], @@ -336,43 +337,43 @@ export const screenshots = [ ["libraries.designsystem.theme.components_FloatingActionButton_Floating_Action_Buttons_en","",0,], ["libraries.designsystem.atomic.pages_FlowStepPage_Day_0_en","libraries.designsystem.atomic.pages_FlowStepPage_Night_0_en",0,], ["features.messages.impl.timeline.focus_FocusRequestStateView_Day_0_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_0_en",0,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_1_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_1_en",20412,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20412,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20412,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_1_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_1_en",20413,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20413,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20413,], ["features.messages.impl.timeline.components_FocusedEvent_Day_0_en","features.messages.impl.timeline.components_FocusedEvent_Night_0_en",0,], ["libraries.textcomposer.components_FormattingOption_Day_0_en","libraries.textcomposer.components_FormattingOption_Night_0_en",0,], ["features.forward.impl_ForwardMessagesView_Day_0_en","features.forward.impl_ForwardMessagesView_Night_0_en",0,], ["features.forward.impl_ForwardMessagesView_Day_1_en","features.forward.impl_ForwardMessagesView_Night_1_en",0,], ["features.forward.impl_ForwardMessagesView_Day_2_en","features.forward.impl_ForwardMessagesView_Night_2_en",0,], -["features.forward.impl_ForwardMessagesView_Day_3_en","features.forward.impl_ForwardMessagesView_Night_3_en",20412,], -["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20412,], +["features.forward.impl_ForwardMessagesView_Day_3_en","features.forward.impl_ForwardMessagesView_Night_3_en",20413,], +["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20413,], ["libraries.designsystem.components.button_GradientFloatingActionButtonCircleShape_Day_0_en","libraries.designsystem.components.button_GradientFloatingActionButtonCircleShape_Night_0_en",0,], ["libraries.designsystem.components.button_GradientFloatingActionButton_Day_0_en","libraries.designsystem.components.button_GradientFloatingActionButton_Night_0_en",0,], ["features.messages.impl.timeline.components.group_GroupHeaderView_Day_0_en","features.messages.impl.timeline.components.group_GroupHeaderView_Night_0_en",0,], ["libraries.designsystem.atomic.pages_HeaderFooterPageScrollable_Day_0_en","libraries.designsystem.atomic.pages_HeaderFooterPageScrollable_Night_0_en",0,], ["libraries.designsystem.atomic.pages_HeaderFooterPage_Day_0_en","libraries.designsystem.atomic.pages_HeaderFooterPage_Night_0_en",0,], -["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20412,], -["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20412,], -["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20412,], -["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20412,], -["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20412,], +["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20413,], +["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20413,], +["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20413,], +["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20413,], +["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20413,], ["features.home.impl_HomeViewA11y_en","",0,], -["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20412,], -["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20412,], +["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20413,], +["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20413,], ["features.home.impl_HomeView_Day_11_en","features.home.impl_HomeView_Night_11_en",0,], ["features.home.impl_HomeView_Day_12_en","features.home.impl_HomeView_Night_12_en",0,], -["features.home.impl_HomeView_Day_13_en","features.home.impl_HomeView_Night_13_en",20412,], -["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20412,], -["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20412,], -["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20412,], -["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20412,], -["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20412,], -["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20412,], -["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20412,], -["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20412,], -["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20412,], -["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20412,], -["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20412,], +["features.home.impl_HomeView_Day_13_en","features.home.impl_HomeView_Night_13_en",20413,], +["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20413,], +["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20413,], +["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20413,], +["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20413,], +["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20413,], +["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20413,], +["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20413,], +["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20413,], +["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20413,], +["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20413,], +["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20413,], ["libraries.designsystem.theme.components_HorizontalDivider_Dividers_en","",0,], ["libraries.designsystem.ruler_HorizontalRuler_Day_0_en","libraries.designsystem.ruler_HorizontalRuler_Night_0_en",0,], ["libraries.designsystem.theme.components_IconButton_Buttons_en","",0,], @@ -385,8 +386,8 @@ export const screenshots = [ ["appicon.enterprise_Icon_en","",0,], ["libraries.designsystem.icons_IconsOther_Day_0_en","libraries.designsystem.icons_IconsOther_Night_0_en",0,], ["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_0_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_0_en",0,], -["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_1_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_1_en",20412,], -["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20412,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_1_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_1_en",20413,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20413,], ["libraries.mediaviewer.impl.gallery.ui_ImageItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_ImageItemView_Night_0_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_0_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_0_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_10_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_10_en",0,], @@ -394,109 +395,109 @@ export const screenshots = [ ["libraries.matrix.ui.messages.reply_InReplyToView_Day_1_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_1_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_2_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_2_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_3_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_3_en",0,], -["libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en",20412,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en",20413,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_5_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_5_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_6_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_6_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_7_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_7_en",0,], -["libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en",20412,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en",20413,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_9_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_9_en",0,], -["features.call.impl.ui_IncomingCallScreen_Day_0_en","features.call.impl.ui_IncomingCallScreen_Night_0_en",20412,], +["features.call.impl.ui_IncomingCallScreen_Day_0_en","features.call.impl.ui_IncomingCallScreen_Night_0_en",20413,], ["features.verifysession.impl.incoming_IncomingVerificationViewA11y_en","",0,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20412,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20412,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20412,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20412,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20412,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20412,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20412,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20412,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20412,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20412,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20412,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20412,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20412,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20412,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20413,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20413,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20413,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20413,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20413,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20413,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20413,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20413,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20413,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20413,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20413,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20413,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20413,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20413,], ["libraries.designsystem.atomic.molecules_InfoListItemMolecule_Day_0_en","libraries.designsystem.atomic.molecules_InfoListItemMolecule_Night_0_en",0,], ["libraries.designsystem.atomic.organisms_InfoListOrganism_Day_0_en","libraries.designsystem.atomic.organisms_InfoListOrganism_Night_0_en",0,], ["libraries.matrix.ui.media_InitialsAvatarBitmapGenerator_Day_0_en","libraries.matrix.ui.media_InitialsAvatarBitmapGenerator_Night_0_en",0,], -["features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en","features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en",20412,], -["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20412,], -["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20412,], +["features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en","features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en",20413,], +["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20413,], +["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20413,], ["features.invitepeople.impl_InvitePeopleView_Day_2_en","features.invitepeople.impl_InvitePeopleView_Night_2_en",0,], ["features.invitepeople.impl_InvitePeopleView_Day_3_en","features.invitepeople.impl_InvitePeopleView_Night_3_en",0,], -["features.invitepeople.impl_InvitePeopleView_Day_4_en","features.invitepeople.impl_InvitePeopleView_Night_4_en",20412,], -["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20412,], -["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20412,], -["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20412,], +["features.invitepeople.impl_InvitePeopleView_Day_4_en","features.invitepeople.impl_InvitePeopleView_Night_4_en",20413,], +["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20413,], +["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20413,], +["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20413,], ["features.invitepeople.impl_InvitePeopleView_Day_8_en","features.invitepeople.impl_InvitePeopleView_Night_8_en",0,], -["features.invitepeople.impl_InvitePeopleView_Day_9_en","features.invitepeople.impl_InvitePeopleView_Night_9_en",20412,], -["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20412,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20412,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20412,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20412,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20412,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20412,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20412,], +["features.invitepeople.impl_InvitePeopleView_Day_9_en","features.invitepeople.impl_InvitePeopleView_Night_9_en",20413,], +["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20413,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20413,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20413,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20413,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20413,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20413,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20413,], ["features.joinroom.impl_JoinRoomView_Day_0_en","features.joinroom.impl_JoinRoomView_Night_0_en",0,], -["features.joinroom.impl_JoinRoomView_Day_10_en","features.joinroom.impl_JoinRoomView_Night_10_en",20412,], -["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20412,], -["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20412,], -["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20412,], -["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20412,], -["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20412,], -["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20412,], -["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20412,], -["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20412,], -["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20412,], -["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20412,], -["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20412,], -["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20412,], -["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20412,], -["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20412,], -["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20412,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20412,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20412,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20412,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20412,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20412,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20412,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20412,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20412,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20412,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20412,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20412,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20412,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20412,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20412,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20412,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20412,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20412,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20412,], +["features.joinroom.impl_JoinRoomView_Day_10_en","features.joinroom.impl_JoinRoomView_Night_10_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20413,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20413,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20413,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20413,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20413,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20413,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20413,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20413,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20413,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20413,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20413,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20413,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20413,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20413,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20413,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20413,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20413,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20413,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20413,], ["libraries.designsystem.components_LabelledCheckbox_Toggles_en","",0,], -["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20412,], -["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20412,], +["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20413,], +["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20413,], ["features.leaveroom.impl_LeaveRoomView_Day_0_en","features.leaveroom.impl_LeaveRoomView_Night_0_en",0,], -["features.leaveroom.impl_LeaveRoomView_Day_1_en","features.leaveroom.impl_LeaveRoomView_Night_1_en",20412,], -["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20412,], -["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20412,], -["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20412,], -["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20412,], -["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20412,], -["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20412,], -["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20412,], -["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20412,], -["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20412,], -["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20412,], -["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20412,], -["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20412,], -["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20412,], -["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20412,], -["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20412,], -["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20412,], +["features.leaveroom.impl_LeaveRoomView_Day_1_en","features.leaveroom.impl_LeaveRoomView_Night_1_en",20413,], +["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20413,], +["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20413,], +["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20413,], +["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20413,], +["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20413,], +["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20413,], +["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20413,], +["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20413,], +["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20413,], +["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20413,], +["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20413,], +["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20413,], +["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20413,], +["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20413,], +["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20413,], +["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20413,], ["libraries.designsystem.background_LightGradientBackground_Day_0_en","libraries.designsystem.background_LightGradientBackground_Night_0_en",0,], ["libraries.designsystem.theme.components_LinearProgressIndicator_Progress_Indicators_en","",0,], ["features.messages.impl.link_LinkView_Day_0_en","features.messages.impl.link_LinkView_Night_0_en",0,], -["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20412,], +["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20413,], ["libraries.designsystem.components.dialogs_ListDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_ListDialog_Day_0_en","libraries.designsystem.components.dialogs_ListDialog_Night_0_en",0,], ["libraries.designsystem.theme.components_ListItemPrimaryActionWithIcon_List_item_-_Primary_action_&_Icon_List_items_en","",0,], @@ -551,38 +552,38 @@ export const screenshots = [ ["libraries.designsystem.theme.components_ListSupportingTextSmallPadding_List_supporting_text_-_small_padding_List_sections_en","",0,], ["libraries.textcomposer.components_LiveWaveformView_Day_0_en","libraries.textcomposer.components_LiveWaveformView_Night_0_en",0,], ["appnav.room.joined_LoadingRoomNodeView_Day_0_en","appnav.room.joined_LoadingRoomNodeView_Night_0_en",0,], -["appnav.room.joined_LoadingRoomNodeView_Day_1_en","appnav.room.joined_LoadingRoomNodeView_Night_1_en",20412,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20412,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20412,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20412,], +["appnav.room.joined_LoadingRoomNodeView_Day_1_en","appnav.room.joined_LoadingRoomNodeView_Night_1_en",20413,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20413,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20413,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20413,], ["appnav.loggedin_LoggedInView_Day_0_en","appnav.loggedin_LoggedInView_Night_0_en",0,], -["appnav.loggedin_LoggedInView_Day_1_en","appnav.loggedin_LoggedInView_Night_1_en",20412,], -["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20412,], -["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20412,], -["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20412,], -["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20412,], -["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20412,], -["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20412,], -["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20412,], -["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20412,], -["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20412,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20412,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20412,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20412,], -["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20412,], -["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20412,], -["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20412,], -["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20412,], -["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20412,], -["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20412,], -["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20412,], -["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20412,], -["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20412,], -["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20412,], -["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20412,], -["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20412,], +["appnav.loggedin_LoggedInView_Day_1_en","appnav.loggedin_LoggedInView_Night_1_en",20413,], +["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20413,], +["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20413,], +["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20413,], +["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20413,], +["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20413,], +["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20413,], +["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20413,], +["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20413,], +["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20413,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20413,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20413,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20413,], +["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20413,], +["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20413,], +["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20413,], +["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20413,], +["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20413,], +["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20413,], +["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20413,], +["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20413,], +["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20413,], +["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20413,], +["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20413,], +["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20413,], ["libraries.designsystem.components.button_MainActionButton_Buttons_en","",0,], -["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20412,], +["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20413,], ["libraries.textcomposer.components.markdown_MarkdownTextInput_Day_0_en","libraries.textcomposer.components.markdown_MarkdownTextInput_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_MatrixBadgeAtomInfo_Day_0_en","libraries.designsystem.atomic.atoms_MatrixBadgeAtomInfo_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_MatrixBadgeAtomNegative_Day_0_en","libraries.designsystem.atomic.atoms_MatrixBadgeAtomNegative_Night_0_en",0,], @@ -595,22 +596,22 @@ export const screenshots = [ ["libraries.matrix.ui.components_MatrixUserRow_Day_1_en","libraries.matrix.ui.components_MatrixUserRow_Night_1_en",0,], ["libraries.mediaviewer.impl.local.audio_MediaAudioView_Day_0_en","libraries.mediaviewer.impl.local.audio_MediaAudioView_Night_0_en",0,], ["libraries.mediaviewer.impl.local.audio_MediaAudioView_Day_1_en","libraries.mediaviewer.impl.local.audio_MediaAudioView_Night_1_en",0,], -["libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Night_0_en",20412,], -["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20412,], +["libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Night_0_en",20413,], +["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20413,], ["libraries.mediaviewer.impl.local.file_MediaFileView_Day_0_en","libraries.mediaviewer.impl.local.file_MediaFileView_Night_0_en",0,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_0_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_0_en",20412,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20412,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20412,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20412,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20412,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20412,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20412,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20412,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20412,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20412,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20412,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20412,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20412,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_0_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_0_en",20413,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20413,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20413,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20413,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20413,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20413,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20413,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20413,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20413,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20413,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20413,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20413,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20413,], ["libraries.mediaviewer.impl.local.image_MediaImageView_Day_0_en","libraries.mediaviewer.impl.local.image_MediaImageView_Night_0_en",0,], ["libraries.mediaviewer.impl.local.player_MediaPlayerControllerView_Day_0_en","libraries.mediaviewer.impl.local.player_MediaPlayerControllerView_Night_0_en",0,], ["libraries.mediaviewer.impl.local.player_MediaPlayerControllerView_Day_1_en","libraries.mediaviewer.impl.local.player_MediaPlayerControllerView_Night_1_en",0,], @@ -618,14 +619,14 @@ export const screenshots = [ ["libraries.mediaviewer.impl.local.video_MediaVideoView_Day_0_en","libraries.mediaviewer.impl.local.video_MediaVideoView_Night_0_en",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_0_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_10_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_11_en","",20412,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20412,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_11_en","",20413,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20413,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_13_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20412,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20413,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_15_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_16_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_1_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_2_en","",20412,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_2_en","",20413,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_3_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_4_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_5_en","",0,], @@ -639,7 +640,7 @@ export const screenshots = [ ["libraries.textcomposer.mentions_MentionSpanTheme_Day_0_en","libraries.textcomposer.mentions_MentionSpanTheme_Night_0_en",0,], ["libraries.designsystem.theme.components.previews_Menu_Menus_en","",0,], ["features.messages.impl.messagecomposer_MessageComposerViewVoice_Day_0_en","features.messages.impl.messagecomposer_MessageComposerViewVoice_Night_0_en",0,], -["features.messages.impl.messagecomposer_MessageComposerView_Day_0_en","features.messages.impl.messagecomposer_MessageComposerView_Night_0_en",20412,], +["features.messages.impl.messagecomposer_MessageComposerView_Day_0_en","features.messages.impl.messagecomposer_MessageComposerView_Night_0_en",20413,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_0_en","features.messages.impl.timeline.components_MessageEventBubble_Night_0_en",0,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_1_en","features.messages.impl.timeline.components_MessageEventBubble_Night_1_en",0,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_2_en","features.messages.impl.timeline.components_MessageEventBubble_Night_2_en",0,], @@ -648,7 +649,7 @@ export const screenshots = [ ["features.messages.impl.timeline.components_MessageEventBubble_Day_5_en","features.messages.impl.timeline.components_MessageEventBubble_Night_5_en",0,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_6_en","features.messages.impl.timeline.components_MessageEventBubble_Night_6_en",0,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_7_en","features.messages.impl.timeline.components_MessageEventBubble_Night_7_en",0,], -["features.messages.impl.timeline.components_MessageShieldView_Day_0_en","features.messages.impl.timeline.components_MessageShieldView_Night_0_en",20412,], +["features.messages.impl.timeline.components_MessageShieldView_Day_0_en","features.messages.impl.timeline.components_MessageShieldView_Night_0_en",20413,], ["features.messages.impl.timeline.components_MessageStateEventContainer_Day_0_en","features.messages.impl.timeline.components_MessageStateEventContainer_Night_0_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButtonAdd_Day_0_en","features.messages.impl.timeline.components_MessagesReactionButtonAdd_Night_0_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButtonExtra_Day_0_en","features.messages.impl.timeline.components_MessagesReactionButtonExtra_Night_0_en",0,], @@ -656,137 +657,137 @@ export const screenshots = [ ["features.messages.impl.timeline.components_MessagesReactionButton_Day_1_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_1_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_2_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_2_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_3_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_3_en",0,], -["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20412,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20412,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20412,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20412,], -["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20412,], -["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20412,], -["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20412,], -["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20412,], -["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20412,], -["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20412,], -["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20412,], -["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20412,], -["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20412,], -["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20412,], +["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20413,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20413,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20413,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20413,], +["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20413,], +["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20413,], +["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20413,], +["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20413,], +["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20413,], +["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20413,], +["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20413,], +["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20413,], +["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20413,], +["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20413,], ["features.migration.impl_MigrationView_Day_0_en","features.migration.impl_MigrationView_Night_0_en",0,], -["features.migration.impl_MigrationView_Day_1_en","features.migration.impl_MigrationView_Night_1_en",20412,], +["features.migration.impl_MigrationView_Day_1_en","features.migration.impl_MigrationView_Night_1_en",20413,], ["libraries.designsystem.theme.components_ModalBottomSheetDark_Bottom_Sheets_en","",0,], ["libraries.designsystem.theme.components_ModalBottomSheetLight_Bottom_Sheets_en","",0,], ["appicon.element_MonochromeIcon_en","",0,], -["features.preferences.impl.root_MultiAccountSection_Day_0_en","features.preferences.impl.root_MultiAccountSection_Night_0_en",20412,], +["features.preferences.impl.root_MultiAccountSection_Day_0_en","features.preferences.impl.root_MultiAccountSection_Night_0_en",20413,], ["libraries.designsystem.components.dialogs_MultipleSelectionDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_MultipleSelectionDialog_Day_0_en","libraries.designsystem.components.dialogs_MultipleSelectionDialog_Night_0_en",0,], ["libraries.designsystem.components.list_MutipleSelectionListItemSelectedTrailingContent_Multiple_selection_List_item_-_selection_in_trailing_content_List_items_en","",0,], ["libraries.designsystem.components.list_MutipleSelectionListItemSelected_Multiple_selection_List_item_-_selection_in_supporting_text_List_items_en","",0,], ["libraries.designsystem.components.list_MutipleSelectionListItem_Multiple_selection_List_item_-_no_selection_List_items_en","",0,], ["libraries.designsystem.theme.components_NavigationBar_App_Bars_en","",0,], -["features.home.impl.components_NewNotificationSoundBanner_Day_0_en","features.home.impl.components_NewNotificationSoundBanner_Night_0_en",20412,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20412,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20412,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20412,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20412,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20412,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20412,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20412,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20412,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20412,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20412,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20412,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20412,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20412,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20412,], -["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20412,], +["features.home.impl.components_NewNotificationSoundBanner_Day_0_en","features.home.impl.components_NewNotificationSoundBanner_Night_0_en",20413,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20413,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20413,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20413,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20413,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20413,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20413,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20413,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20413,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20413,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20413,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20413,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20413,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20413,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20413,], +["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20413,], ["libraries.designsystem.atomic.pages_OnBoardingPage_Day_0_en","libraries.designsystem.atomic.pages_OnBoardingPage_Night_0_en",0,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_0_en","features.login.impl.screens.onboarding_OnBoardingView_Night_0_en",20412,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20412,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20412,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20412,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20412,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20412,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20412,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20412,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_0_en","features.login.impl.screens.onboarding_OnBoardingView_Night_0_en",20413,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20413,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20413,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20413,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20413,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20413,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20413,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20413,], ["libraries.designsystem.background_OnboardingBackground_Day_0_en","libraries.designsystem.background_OnboardingBackground_Night_0_en",0,], -["libraries.matrix.ui.components_OrganizationHeader_Day_0_en","libraries.matrix.ui.components_OrganizationHeader_Night_0_en",20412,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20412,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20412,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20412,], +["libraries.matrix.ui.components_OrganizationHeader_Day_0_en","libraries.matrix.ui.components_OrganizationHeader_Night_0_en",20413,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20413,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20413,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20413,], ["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_12_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_12_en",0,], ["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_13_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_13_en",0,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en",20412,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20412,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20412,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20412,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20412,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20412,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20412,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20412,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20412,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en",20413,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20413,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20413,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20413,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20413,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20413,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20413,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20413,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20413,], ["libraries.designsystem.theme.components_OutlinedButtonLargeLowPadding_Buttons_en","",0,], ["libraries.designsystem.theme.components_OutlinedButtonLarge_Buttons_en","",0,], ["libraries.designsystem.theme.components_OutlinedButtonMediumLowPadding_Buttons_en","",0,], ["libraries.designsystem.theme.components_OutlinedButtonMedium_Buttons_en","",0,], ["libraries.designsystem.theme.components_OutlinedButtonSmall_Buttons_en","",0,], -["libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Day_0_en","libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Night_0_en",20412,], -["features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_en","features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Night_0_en",20412,], -["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20412,], -["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20412,], -["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20412,], -["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20412,], +["libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Day_0_en","libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Night_0_en",20413,], +["features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_en","features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Night_0_en",20413,], +["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20413,], +["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20413,], +["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20413,], +["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20413,], ["features.lockscreen.impl.components_PinEntryTextField_Day_0_en","features.lockscreen.impl.components_PinEntryTextField_Night_0_en",0,], ["libraries.designsystem.components_PinIcon_Day_0_en","libraries.designsystem.components_PinIcon_Night_0_en",0,], ["features.lockscreen.impl.unlock.keypad_PinKeypad_Day_0_en","features.lockscreen.impl.unlock.keypad_PinKeypad_Night_0_en",0,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_0_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_0_en",20412,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20412,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20412,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20412,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20412,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20412,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20412,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20412,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20412,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20412,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20412,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20412,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20412,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20412,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20412,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20412,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_0_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_0_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20413,], ["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_0_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_0_en",0,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_10_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_10_en",20412,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20412,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20412,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20412,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20412,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20412,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20412,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20412,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20412,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20412,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20412,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20412,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20412,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20412,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_10_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_10_en",20413,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20413,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20413,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20413,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20413,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20413,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20413,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20413,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20413,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20413,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20413,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20413,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20413,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20413,], ["libraries.designsystem.atomic.atoms_PlaceholderAtom_Day_0_en","libraries.designsystem.atomic.atoms_PlaceholderAtom_Night_0_en",0,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20412,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20412,], -["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20412,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20412,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20412,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20413,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20413,], +["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20413,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20413,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20413,], ["features.poll.api.pollcontent_PollAnswerViewUndisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewUndisclosedNotSelected_Night_0_en",0,], ["features.poll.api.pollcontent_PollAnswerViewUndisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewUndisclosedSelected_Night_0_en",0,], -["features.poll.api.pollcontent_PollContentViewCreatorEditable_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEditable_Night_0_en",20412,], -["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20412,], -["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20412,], -["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20412,], -["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20412,], -["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20412,], -["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20412,], -["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20412,], -["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20412,], -["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20412,], -["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20412,], +["features.poll.api.pollcontent_PollContentViewCreatorEditable_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEditable_Night_0_en",20413,], +["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20413,], +["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20413,], +["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20413,], +["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20413,], +["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20413,], +["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20413,], +["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20413,], +["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20413,], +["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20413,], +["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20413,], ["features.poll.api.pollcontent_PollTitleView_Day_0_en","features.poll.api.pollcontent_PollTitleView_Night_0_en",0,], ["libraries.designsystem.components.preferences_PreferenceCategory_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceCheckbox_Preferences_en","",0,], @@ -800,211 +801,211 @@ export const screenshots = [ ["libraries.designsystem.components.preferences_PreferenceRow_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceSlide_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceSwitch_Preferences_en","",0,], -["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20412,], -["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20412,], -["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20412,], -["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20412,], +["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20413,], +["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20413,], +["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20413,], +["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20413,], ["features.messages.impl.timeline.components.event_ProgressButton_Day_0_en","features.messages.impl.timeline.components.event_ProgressButton_Night_0_en",0,], -["libraries.designsystem.components_ProgressDialogContent_Dialogs_en","",20412,], -["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20412,], +["libraries.designsystem.components_ProgressDialogContent_Dialogs_en","",20413,], +["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20413,], ["libraries.designsystem.components_ProgressDialogWithTextAndContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithTextAndContent_Night_0_en",0,], -["libraries.designsystem.components_ProgressDialog_Day_0_en","libraries.designsystem.components_ProgressDialog_Night_0_en",20412,], -["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20412,], -["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20412,], -["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20412,], -["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20412,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20412,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20412,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20412,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20412,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20412,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20412,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20412,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20412,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20412,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20412,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20412,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20412,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20412,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20412,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20412,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20412,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20412,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20412,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20412,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20412,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20412,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20412,], +["libraries.designsystem.components_ProgressDialog_Day_0_en","libraries.designsystem.components_ProgressDialog_Night_0_en",20413,], +["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20413,], +["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20413,], +["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20413,], +["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20413,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20413,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20413,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20413,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20413,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20413,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20413,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20413,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20413,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20413,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20413,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20413,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20413,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20413,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20413,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20413,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20413,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20413,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20413,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20413,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20413,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20413,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20413,], ["libraries.designsystem.theme.components_RadioButton_Toggles_en","",0,], -["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20412,], -["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20412,], +["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20413,], +["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20413,], ["features.rageshake.api.preferences_RageshakePreferencesView_Day_1_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_1_en",0,], ["features.messages.impl.timeline.components.reactionsummary_ReactionSummaryViewContent_Day_0_en","features.messages.impl.timeline.components.reactionsummary_ReactionSummaryViewContent_Night_0_en",0,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_0_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_0_en",20412,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20412,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20412,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20412,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20412,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20412,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20412,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20412,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20412,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20412,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20412,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20412,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20412,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20412,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20412,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20412,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20412,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20412,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20412,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20412,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20412,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_0_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_0_en",20413,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20413,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20413,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20413,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20413,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20413,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20413,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20413,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20413,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20413,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20413,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20413,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20413,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20413,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20413,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20413,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20413,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20413,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20413,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20413,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20413,], ["libraries.designsystem.atomic.atoms_RedIndicatorAtom_Day_0_en","libraries.designsystem.atomic.atoms_RedIndicatorAtom_Night_0_en",0,], ["features.messages.impl.timeline.components_ReplySwipeIndicator_Day_0_en","features.messages.impl.timeline.components_ReplySwipeIndicator_Night_0_en",0,], -["features.messages.impl.report_ReportMessageView_Day_0_en","features.messages.impl.report_ReportMessageView_Night_0_en",20412,], -["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20412,], -["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20412,], -["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20412,], -["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20412,], -["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20412,], -["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20412,], -["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20412,], -["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20412,], -["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20412,], -["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20412,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20412,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20412,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20412,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20412,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20412,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20412,], +["features.messages.impl.report_ReportMessageView_Day_0_en","features.messages.impl.report_ReportMessageView_Night_0_en",20413,], +["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20413,], +["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20413,], +["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20413,], +["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20413,], +["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20413,], +["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20413,], +["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20413,], +["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20413,], +["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20413,], +["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20413,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20413,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20413,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20413,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20413,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20413,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20413,], ["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_0_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_0_en",0,], -["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_1_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_1_en",20412,], -["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20412,], -["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20412,], -["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20412,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20412,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20412,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20412,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20412,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20412,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20412,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20412,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20412,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20412,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_1_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_1_en",20413,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20413,], +["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20413,], +["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20413,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20413,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20413,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20413,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20413,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20413,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20413,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20413,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20413,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20413,], ["libraries.matrix.ui.room.address_RoomAddressField_Day_0_en","libraries.matrix.ui.room.address_RoomAddressField_Night_0_en",0,], ["features.roomaliasresolver.impl_RoomAliasResolverView_Day_0_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_0_en",0,], -["features.roomaliasresolver.impl_RoomAliasResolverView_Day_1_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_1_en",20412,], -["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20412,], -["features.roomdetails.impl_RoomDetailsDark_0_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_10_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_11_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_12_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_13_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_14_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_15_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_16_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_17_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_18_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_19_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_1_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_2_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_3_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_4_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_5_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_6_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_7_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_8_en","",20412,], -["features.roomdetails.impl_RoomDetailsDark_9_en","",20412,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_0_en",20412,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_1_en",20412,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_2_en",20412,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_3_en",20412,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_4_en",20412,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_5_en",20412,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_6_en",20412,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_7_en",20412,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_8_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_8_en",20412,], -["features.roomdetails.impl_RoomDetails_0_en","",20412,], -["features.roomdetails.impl_RoomDetails_10_en","",20412,], -["features.roomdetails.impl_RoomDetails_11_en","",20412,], -["features.roomdetails.impl_RoomDetails_12_en","",20412,], -["features.roomdetails.impl_RoomDetails_13_en","",20412,], -["features.roomdetails.impl_RoomDetails_14_en","",20412,], -["features.roomdetails.impl_RoomDetails_15_en","",20412,], -["features.roomdetails.impl_RoomDetails_16_en","",20412,], -["features.roomdetails.impl_RoomDetails_17_en","",20412,], -["features.roomdetails.impl_RoomDetails_18_en","",20412,], -["features.roomdetails.impl_RoomDetails_19_en","",20412,], -["features.roomdetails.impl_RoomDetails_1_en","",20412,], -["features.roomdetails.impl_RoomDetails_2_en","",20412,], -["features.roomdetails.impl_RoomDetails_3_en","",20412,], -["features.roomdetails.impl_RoomDetails_4_en","",20412,], -["features.roomdetails.impl_RoomDetails_5_en","",20412,], -["features.roomdetails.impl_RoomDetails_6_en","",20412,], -["features.roomdetails.impl_RoomDetails_7_en","",20412,], -["features.roomdetails.impl_RoomDetails_8_en","",20412,], -["features.roomdetails.impl_RoomDetails_9_en","",20412,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20412,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20412,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20412,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20412,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20412,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20412,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20412,], -["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20412,], -["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20412,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_1_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_1_en",20413,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20413,], +["features.roomdetails.impl_RoomDetailsDark_0_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_10_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_11_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_12_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_13_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_14_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_15_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_16_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_17_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_18_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_19_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_1_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_2_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_3_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_4_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_5_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_6_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_7_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_8_en","",20413,], +["features.roomdetails.impl_RoomDetailsDark_9_en","",20413,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_0_en",20413,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_1_en",20413,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_2_en",20413,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_3_en",20413,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_4_en",20413,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_5_en",20413,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_6_en",20413,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_7_en",20413,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_8_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_8_en",20413,], +["features.roomdetails.impl_RoomDetails_0_en","",20413,], +["features.roomdetails.impl_RoomDetails_10_en","",20413,], +["features.roomdetails.impl_RoomDetails_11_en","",20413,], +["features.roomdetails.impl_RoomDetails_12_en","",20413,], +["features.roomdetails.impl_RoomDetails_13_en","",20413,], +["features.roomdetails.impl_RoomDetails_14_en","",20413,], +["features.roomdetails.impl_RoomDetails_15_en","",20413,], +["features.roomdetails.impl_RoomDetails_16_en","",20413,], +["features.roomdetails.impl_RoomDetails_17_en","",20413,], +["features.roomdetails.impl_RoomDetails_18_en","",20413,], +["features.roomdetails.impl_RoomDetails_19_en","",20413,], +["features.roomdetails.impl_RoomDetails_1_en","",20413,], +["features.roomdetails.impl_RoomDetails_2_en","",20413,], +["features.roomdetails.impl_RoomDetails_3_en","",20413,], +["features.roomdetails.impl_RoomDetails_4_en","",20413,], +["features.roomdetails.impl_RoomDetails_5_en","",20413,], +["features.roomdetails.impl_RoomDetails_6_en","",20413,], +["features.roomdetails.impl_RoomDetails_7_en","",20413,], +["features.roomdetails.impl_RoomDetails_8_en","",20413,], +["features.roomdetails.impl_RoomDetails_9_en","",20413,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20413,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20413,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20413,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20413,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20413,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20413,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20413,], +["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20413,], +["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20413,], ["features.home.impl.components_RoomListContentView_Day_2_en","features.home.impl.components_RoomListContentView_Night_2_en",0,], -["features.home.impl.components_RoomListContentView_Day_3_en","features.home.impl.components_RoomListContentView_Night_3_en",20412,], -["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20412,], -["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20412,], -["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20412,], -["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20412,], -["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20412,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20412,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20412,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20412,], +["features.home.impl.components_RoomListContentView_Day_3_en","features.home.impl.components_RoomListContentView_Night_3_en",20413,], +["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20413,], +["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20413,], +["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20413,], +["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20413,], +["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20413,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20413,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20413,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20413,], ["features.home.impl.search_RoomListSearchContent_Day_0_en","features.home.impl.search_RoomListSearchContent_Night_0_en",0,], -["features.home.impl.search_RoomListSearchContent_Day_1_en","features.home.impl.search_RoomListSearchContent_Night_1_en",20412,], -["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_0_en",20412,], -["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_1_en",20412,], -["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_2_en",20412,], -["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20412,], -["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20412,], -["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20412,], -["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20412,], -["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20412,], -["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20412,], +["features.home.impl.search_RoomListSearchContent_Day_1_en","features.home.impl.search_RoomListSearchContent_Night_1_en",20413,], +["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_0_en",20413,], +["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_1_en",20413,], +["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_2_en",20413,], +["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20413,], +["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20413,], +["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20413,], +["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20413,], +["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20413,], +["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20413,], ["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",0,], -["features.roomdetails.impl.members_RoomMemberListView_Day_7_en","features.roomdetails.impl.members_RoomMemberListView_Night_7_en",20412,], -["features.roomdetails.impl.members_RoomMemberListView_Day_8_en","features.roomdetails.impl.members_RoomMemberListView_Night_8_en",20412,], -["features.roomdetails.impl.members_RoomMemberListView_Day_9_en","features.roomdetails.impl.members_RoomMemberListView_Night_9_en",20412,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20412,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20412,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20412,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20412,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20412,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20412,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20412,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20412,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20412,], +["features.roomdetails.impl.members_RoomMemberListView_Day_7_en","features.roomdetails.impl.members_RoomMemberListView_Night_7_en",20413,], +["features.roomdetails.impl.members_RoomMemberListView_Day_8_en","features.roomdetails.impl.members_RoomMemberListView_Night_8_en",20413,], +["features.roomdetails.impl.members_RoomMemberListView_Day_9_en","features.roomdetails.impl.members_RoomMemberListView_Night_9_en",20413,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20413,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20413,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20413,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20413,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20413,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20413,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20413,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20413,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20413,], ["features.roommembermoderation.impl_RoomMemberModerationView_Day_9_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_9_en",0,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20412,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20412,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20412,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20412,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20412,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20412,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20412,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20412,], -["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20412,], -["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20412,], -["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20412,], -["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20412,], -["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20412,], -["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20412,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20413,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20413,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20413,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20413,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20413,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20413,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20413,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20413,], +["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20413,], +["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20413,], +["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20413,], +["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20413,], +["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20413,], +["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20413,], ["features.home.impl.components_RoomSummaryPlaceholderRow_Day_0_en","features.home.impl.components_RoomSummaryPlaceholderRow_Night_0_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_0_en","features.home.impl.components_RoomSummaryRow_Night_0_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_10_en","features.home.impl.components_RoomSummaryRow_Night_10_en",0,], @@ -1027,14 +1028,14 @@ export const screenshots = [ ["features.home.impl.components_RoomSummaryRow_Day_26_en","features.home.impl.components_RoomSummaryRow_Night_26_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_27_en","features.home.impl.components_RoomSummaryRow_Night_27_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_28_en","features.home.impl.components_RoomSummaryRow_Night_28_en",0,], -["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20412,], -["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20412,], -["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20412,], -["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20412,], -["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20412,], -["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20412,], -["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20412,], -["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20412,], +["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20413,], +["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20413,], +["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20413,], +["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20413,], +["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20413,], +["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20413,], +["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20413,], +["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20413,], ["features.home.impl.components_RoomSummaryRow_Day_3_en","features.home.impl.components_RoomSummaryRow_Night_3_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_4_en","features.home.impl.components_RoomSummaryRow_Night_4_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_5_en","features.home.impl.components_RoomSummaryRow_Night_5_en",0,], @@ -1042,83 +1043,83 @@ export const screenshots = [ ["features.home.impl.components_RoomSummaryRow_Day_7_en","features.home.impl.components_RoomSummaryRow_Night_7_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_8_en","features.home.impl.components_RoomSummaryRow_Night_8_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_9_en","features.home.impl.components_RoomSummaryRow_Night_9_en",0,], -["appnav.root_RootView_Day_0_en","appnav.root_RootView_Night_0_en",20412,], -["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20412,], -["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20412,], +["appnav.root_RootView_Day_0_en","appnav.root_RootView_Night_0_en",20413,], +["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20413,], +["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20413,], ["appicon.enterprise_RoundIcon_en","",0,], ["appicon.element_RoundIcon_en","",0,], ["libraries.designsystem.atomic.atoms_RoundedIconAtom_Day_0_en","libraries.designsystem.atomic.atoms_RoundedIconAtom_Night_0_en",0,], -["features.verifysession.impl.emoji_SasEmojis_Day_0_en","features.verifysession.impl.emoji_SasEmojis_Night_0_en",20412,], -["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20412,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20412,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20412,], +["features.verifysession.impl.emoji_SasEmojis_Day_0_en","features.verifysession.impl.emoji_SasEmojis_Night_0_en",20413,], +["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20413,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20413,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20413,], ["libraries.designsystem.theme.components_SearchBarActiveNoneQuery_Search_views_en","",0,], ["libraries.designsystem.theme.components_SearchBarActiveWithContent_Search_views_en","",0,], -["libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en","",20412,], +["libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en","",20413,], ["libraries.designsystem.theme.components_SearchBarActiveWithQueryNoBackButton_Search_views_en","",0,], ["libraries.designsystem.theme.components_SearchBarActiveWithQuery_Search_views_en","",0,], ["libraries.designsystem.theme.components_SearchBarInactive_Search_views_en","",0,], -["features.startchat.impl.components_SearchMultipleUsersResultItem_en","",20412,], -["features.startchat.impl.components_SearchSingleUserResultItem_en","",20412,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20412,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20412,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20412,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20412,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20412,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20412,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20412,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20412,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20412,], -["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20412,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20412,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20412,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20412,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20412,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20412,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20412,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20412,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20412,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20412,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20412,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20412,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_0_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_5_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_6_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_7_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_8_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_9_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_0_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_5_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_6_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_7_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_8_en","",20412,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_9_en","",20412,], +["features.startchat.impl.components_SearchMultipleUsersResultItem_en","",20413,], +["features.startchat.impl.components_SearchSingleUserResultItem_en","",20413,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20413,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20413,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20413,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20413,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20413,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20413,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20413,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20413,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20413,], +["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20413,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20413,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20413,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20413,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20413,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20413,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20413,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20413,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20413,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20413,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20413,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20413,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_0_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_5_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_6_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_7_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_8_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_9_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_0_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_5_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_6_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_7_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_8_en","",20413,], +["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_9_en","",20413,], ["libraries.designsystem.atomic.atoms_SelectedIndicatorAtom_Day_0_en","libraries.designsystem.atomic.atoms_SelectedIndicatorAtom_Night_0_en",0,], ["libraries.matrix.ui.components_SelectedRoomRtl_Day_0_en","libraries.matrix.ui.components_SelectedRoomRtl_Night_0_en",0,], ["libraries.matrix.ui.components_SelectedRoomRtl_Day_1_en","libraries.matrix.ui.components_SelectedRoomRtl_Night_1_en",0,], @@ -1132,11 +1133,11 @@ export const screenshots = [ ["libraries.matrix.ui.components_SelectedUser_Day_1_en","libraries.matrix.ui.components_SelectedUser_Night_1_en",0,], ["libraries.matrix.ui.components_SelectedUsersRowList_Day_0_en","libraries.matrix.ui.components_SelectedUsersRowList_Night_0_en",0,], ["libraries.textcomposer.components_SendButton_Day_0_en","libraries.textcomposer.components_SendButton_Night_0_en",0,], -["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20412,], -["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20412,], -["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20412,], -["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20412,], -["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20412,], +["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20413,], +["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20413,], +["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20413,], +["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20413,], +["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20413,], ["libraries.matrix.ui.messages.sender_SenderName_Day_0_en","libraries.matrix.ui.messages.sender_SenderName_Night_0_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_1_en","libraries.matrix.ui.messages.sender_SenderName_Night_1_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_2_en","libraries.matrix.ui.messages.sender_SenderName_Night_2_en",0,], @@ -1146,27 +1147,27 @@ export const screenshots = [ ["libraries.matrix.ui.messages.sender_SenderName_Day_6_en","libraries.matrix.ui.messages.sender_SenderName_Night_6_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_7_en","libraries.matrix.ui.messages.sender_SenderName_Night_7_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_8_en","libraries.matrix.ui.messages.sender_SenderName_Night_8_en",0,], -["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20412,], -["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20412,], -["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20412,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20412,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20412,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20412,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20412,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20412,], +["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20413,], +["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20413,], +["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20413,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20413,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20413,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20413,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20413,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20413,], ["features.share.impl_ShareView_Day_0_en","features.share.impl_ShareView_Night_0_en",0,], ["features.share.impl_ShareView_Day_1_en","features.share.impl_ShareView_Night_1_en",0,], ["features.share.impl_ShareView_Day_2_en","features.share.impl_ShareView_Night_2_en",0,], -["features.share.impl_ShareView_Day_3_en","features.share.impl_ShareView_Night_3_en",20412,], -["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20412,], -["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20412,], -["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20412,], -["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20412,], -["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20412,], -["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20412,], -["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20412,], -["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20412,], -["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20412,], +["features.share.impl_ShareView_Day_3_en","features.share.impl_ShareView_Night_3_en",20413,], +["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20413,], +["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20413,], +["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20413,], +["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20413,], +["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20413,], +["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20413,], +["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20413,], +["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20413,], +["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20413,], ["libraries.designsystem.components_SimpleModalBottomSheet_Day_0_en","libraries.designsystem.components_SimpleModalBottomSheet_Night_0_en",0,], ["libraries.designsystem.components.dialogs_SingleSelectionDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_SingleSelectionDialog_Day_0_en","libraries.designsystem.components.dialogs_SingleSelectionDialog_Night_0_en",0,], @@ -1176,102 +1177,102 @@ export const screenshots = [ ["libraries.designsystem.components.list_SingleSelectionListItemUnselectedWithSupportingText_Single_selection_List_item_-_no_selection,_supporting_text_List_items_en","",0,], ["libraries.designsystem.components.list_SingleSelectionListItem_Single_selection_List_item_-_no_selection_List_items_en","",0,], ["libraries.designsystem.theme.components_Sliders_Sliders_en","",0,], -["features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Day_0_en","features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Night_0_en",20412,], +["features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Day_0_en","features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Night_0_en",20413,], ["libraries.designsystem.theme.components_SnackbarWithActionAndCloseButton_Snackbar_with_action_and_close_button_Snackbars_en","",0,], ["libraries.designsystem.theme.components_SnackbarWithActionOnNewLineAndCloseButton_Snackbar_with_action_and_close_button_on_new_line_Snackbars_en","",0,], ["libraries.designsystem.theme.components_SnackbarWithActionOnNewLine_Snackbar_with_action_on_new_line_Snackbars_en","",0,], ["libraries.designsystem.theme.components_SnackbarWithAction_Snackbar_with_action_Snackbars_en","",0,], ["libraries.designsystem.theme.components_Snackbar_Snackbar_Snackbars_en","",0,], -["features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en","features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en",20412,], +["features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en","features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en",20413,], ["libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en","",0,], -["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20412,], -["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20412,], -["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20412,], +["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20413,], +["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20413,], +["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20413,], ["libraries.matrix.ui.components_SpaceMembersViewNoHeroes_Day_0_en","libraries.matrix.ui.components_SpaceMembersViewNoHeroes_Night_0_en",0,], ["libraries.matrix.ui.components_SpaceMembersView_Day_0_en","libraries.matrix.ui.components_SpaceMembersView_Night_0_en",0,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_0_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_0_en",20412,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20412,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20412,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20412,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20412,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20412,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20412,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20412,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20412,], -["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20412,], -["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20412,], -["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20412,], -["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20412,], -["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20412,], -["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20412,], -["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20412,], -["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20412,], -["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20412,], -["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20412,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_0_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_0_en",20413,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20413,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20413,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20413,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20413,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20413,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20413,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20413,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20413,], +["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20413,], +["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20413,], +["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20413,], +["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20413,], +["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20413,], +["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20413,], +["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20413,], +["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20413,], +["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20413,], +["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20413,], ["libraries.designsystem.modifiers_SquareSizeModifierInsideSquare_en","",0,], ["libraries.designsystem.modifiers_SquareSizeModifierLargeHeight_en","",0,], ["libraries.designsystem.modifiers_SquareSizeModifierLargeWidth_en","",0,], -["features.startchat.impl.root_StartChatView_Day_0_en","features.startchat.impl.root_StartChatView_Night_0_en",20412,], -["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20412,], -["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20412,], -["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20412,], -["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20412,], -["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20412,], -["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20412,], +["features.startchat.impl.root_StartChatView_Day_0_en","features.startchat.impl.root_StartChatView_Night_0_en",20413,], +["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20413,], +["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20413,], +["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20413,], +["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20413,], +["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20413,], +["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20413,], ["features.location.api_StaticMapView_Day_0_en","features.location.api_StaticMapView_Night_0_en",0,], -["features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en","features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en",20412,], +["features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en","features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en",20413,], ["libraries.designsystem.atomic.pages_SunsetPage_Day_0_en","libraries.designsystem.atomic.pages_SunsetPage_Night_0_en",0,], ["libraries.designsystem.components.button_SuperButton_Day_0_en","libraries.designsystem.components.button_SuperButton_Night_0_en",0,], ["libraries.designsystem.theme.components_Surface_en","",0,], ["libraries.designsystem.theme.components_Switch_Toggles_en","",0,], -["appnav.loggedin_SyncStateView_Day_0_en","appnav.loggedin_SyncStateView_Night_0_en",20412,], +["appnav.loggedin_SyncStateView_Day_0_en","appnav.loggedin_SyncStateView_Night_0_en",20413,], ["libraries.designsystem.components.avatar.internal_TextAvatar_Avatars_en","",0,], ["libraries.designsystem.theme.components_TextButtonLargeLowPadding_Buttons_en","",0,], ["libraries.designsystem.theme.components_TextButtonLarge_Buttons_en","",0,], ["libraries.designsystem.theme.components_TextButtonMediumLowPadding_Buttons_en","",0,], ["libraries.designsystem.theme.components_TextButtonMedium_Buttons_en","",0,], ["libraries.designsystem.theme.components_TextButtonSmall_Buttons_en","",0,], -["libraries.textcomposer_TextComposerAddCaption_Day_0_en","libraries.textcomposer_TextComposerAddCaption_Night_0_en",20412,], -["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20412,], -["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20412,], -["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20412,], -["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20412,], -["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20412,], -["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20412,], -["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20412,], -["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20412,], -["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20412,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20412,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20412,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20412,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20412,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20412,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20412,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20412,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20412,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20412,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20412,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20412,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20412,], -["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20412,], -["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20412,], -["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20412,], -["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20412,], -["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20412,], -["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20412,], -["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20412,], -["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20412,], -["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20412,], -["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20412,], -["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20412,], -["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20412,], -["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20412,], -["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20412,], -["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20412,], +["libraries.textcomposer_TextComposerAddCaption_Day_0_en","libraries.textcomposer_TextComposerAddCaption_Night_0_en",20413,], +["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20413,], +["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20413,], +["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20413,], +["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20413,], +["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20413,], +["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20413,], +["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20413,], +["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20413,], +["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20413,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20413,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20413,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20413,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20413,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20413,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20413,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20413,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20413,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20413,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20413,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20413,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20413,], +["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20413,], +["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20413,], +["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20413,], +["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20413,], +["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20413,], +["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20413,], +["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20413,], +["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20413,], +["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20413,], +["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20413,], +["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20413,], +["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20413,], +["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20413,], +["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20413,], +["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20413,], ["libraries.textcomposer_TextComposerVoice_Day_0_en","libraries.textcomposer_TextComposerVoice_Night_0_en",0,], ["libraries.designsystem.theme.components_TextDark_Text_en","",0,], -["libraries.designsystem.components.dialogs_TextFieldDialogWithError_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialogWithError_Night_0_en",20412,], -["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20412,], +["libraries.designsystem.components.dialogs_TextFieldDialogWithError_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialogWithError_Night_0_en",20413,], +["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20413,], ["libraries.designsystem.components.list_TextFieldListItemEmpty_Text_field_List_item_-_empty_List_items_en","",0,], ["libraries.designsystem.components.list_TextFieldListItemTextFieldValue_Text_field_List_item_-_textfieldvalue_List_items_en","",0,], ["libraries.designsystem.components.list_TextFieldListItem_Text_field_List_item_-_text_List_items_en","",0,], @@ -1283,16 +1284,16 @@ export const screenshots = [ ["libraries.mediaviewer.impl.local.txt_TextFileContentView_Day_3_en","libraries.mediaviewer.impl.local.txt_TextFileContentView_Night_3_en",0,], ["libraries.textcomposer.components_TextFormatting_Day_0_en","libraries.textcomposer.components_TextFormatting_Night_0_en",0,], ["libraries.designsystem.theme.components_TextLight_Text_en","",0,], -["features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en","features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en",20412,], -["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20412,], -["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20412,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20412,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20412,], +["features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en","features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en",20413,], +["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20413,], +["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20413,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20413,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20413,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_0_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_1_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_2_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_2_en",0,], -["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_3_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_3_en",20412,], -["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20412,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_3_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_3_en",20413,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20413,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_5_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_5_en",0,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_6_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_6_en",0,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_7_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_7_en",0,], @@ -1302,18 +1303,18 @@ export const screenshots = [ ["features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_2_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_3_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_4_en",0,], -["features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en","features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en",20412,], +["features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en","features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en",20413,], ["features.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_Night_0_en",0,], ["features.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_Day_1_en","features.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_Night_1_en",0,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_0_en",20412,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20412,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20412,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20412,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20412,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20412,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20412,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20412,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20412,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_0_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20413,], ["features.messages.impl.timeline.components_TimelineItemEventRowDisambiguated_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowDisambiguated_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowForDirectRoom_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowForDirectRoom_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowLongSenderName_en","",0,], @@ -1321,18 +1322,18 @@ export const screenshots = [ ["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_2_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_2_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_3_en",20412,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20412,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_3_en",20413,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20413,], ["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_5_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_5_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_6_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_6_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_7_en",20412,], -["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20412,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20412,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_7_en",20413,], +["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20413,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20413,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Day_2_en","features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Night_2_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en",20412,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20412,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en",20413,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20413,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_0_en",0,], @@ -1341,41 +1342,41 @@ export const screenshots = [ ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_2_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_2_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_3_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20412,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20413,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_5_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_5_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_6_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_6_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_7_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en",20412,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en",20413,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_9_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_9_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en",20412,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en",20413,], ["features.messages.impl.timeline.components_TimelineItemEventRow_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRow_Night_0_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventTimestampBelow_en","",20412,], +["features.messages.impl.timeline.components_TimelineItemEventTimestampBelow_en","",20413,], ["features.messages.impl.timeline.components.event_TimelineItemFileView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemFileView_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemFileView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemFileView_Night_1_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemFileView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemFileView_Night_2_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemFileView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemFileView_Night_3_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemFileView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemFileView_Night_4_en",0,], -["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Night_0_en",20412,], -["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20412,], -["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20412,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Night_0_en",20413,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20413,], ["features.messages.impl.timeline.components.event_TimelineItemImageView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageView_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemImageView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemImageView_Night_1_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemImageView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemImageView_Night_2_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemImageView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemImageView_Night_3_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemInformativeView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemInformativeView_Night_0_en",0,], -["features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Night_0_en",20412,], +["features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Night_0_en",20413,], ["features.messages.impl.timeline.components.event_TimelineItemLocationView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLocationView_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemLocationView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemLocationView_Night_1_en",0,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_0_en",20412,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20412,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20412,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20412,], -["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20412,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_0_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20413,], +["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20413,], ["features.messages.impl.timeline.components_TimelineItemReactionsViewFew_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewFew_Night_0_en",0,], -["features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Night_0_en",20412,], -["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20412,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Night_0_en",20413,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20413,], ["features.messages.impl.timeline.components_TimelineItemReactionsView_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsView_Night_0_en",0,], -["features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Night_0_en",20412,], +["features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Night_0_en",20413,], ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_0_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_0_en",0,], ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_1_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_1_en",0,], ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_2_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_2_en",0,], @@ -1384,8 +1385,8 @@ export const screenshots = [ ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_5_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_5_en",0,], ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_6_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_6_en",0,], ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_7_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_7_en",0,], -["features.messages.impl.timeline.components.event_TimelineItemRedactedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemRedactedView_Night_0_en",20412,], -["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20412,], +["features.messages.impl.timeline.components.event_TimelineItemRedactedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemRedactedView_Night_0_en",20413,], +["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20413,], ["features.messages.impl.timeline.components_TimelineItemStateEventRow_Day_0_en","features.messages.impl.timeline.components_TimelineItemStateEventRow_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemStateView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemStateView_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemStickerView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemStickerView_Night_0_en",0,], @@ -1400,8 +1401,8 @@ export const screenshots = [ ["features.messages.impl.timeline.components.event_TimelineItemTextView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemTextView_Night_3_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemTextView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemTextView_Night_4_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemTextView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemTextView_Night_5_en",0,], -["features.messages.impl.timeline.components.event_TimelineItemUnknownView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemUnknownView_Night_0_en",20412,], -["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20412,], +["features.messages.impl.timeline.components.event_TimelineItemUnknownView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemUnknownView_Night_0_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20413,], ["features.messages.impl.timeline.components.event_TimelineItemVideoView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoView_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemVideoView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemVideoView_Night_1_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemVideoView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemVideoView_Night_2_en",0,], @@ -1424,85 +1425,85 @@ export const screenshots = [ ["features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_9_en","features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_9_en",0,], ["features.messages.impl.timeline.components.virtual_TimelineLoadingMoreIndicator_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineLoadingMoreIndicator_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineVideoWithCaptionRow_Day_0_en","features.messages.impl.timeline.components.event_TimelineVideoWithCaptionRow_Night_0_en",0,], -["features.messages.impl.timeline_TimelineViewMessageShield_Day_0_en","features.messages.impl.timeline_TimelineViewMessageShield_Night_0_en",20412,], -["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20412,], +["features.messages.impl.timeline_TimelineViewMessageShield_Day_0_en","features.messages.impl.timeline_TimelineViewMessageShield_Night_0_en",20413,], +["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20413,], ["features.messages.impl.timeline_TimelineView_Day_10_en","features.messages.impl.timeline_TimelineView_Night_10_en",0,], -["features.messages.impl.timeline_TimelineView_Day_11_en","features.messages.impl.timeline_TimelineView_Night_11_en",20412,], -["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20412,], -["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20412,], -["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20412,], -["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20412,], -["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20412,], -["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20412,], -["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20412,], +["features.messages.impl.timeline_TimelineView_Day_11_en","features.messages.impl.timeline_TimelineView_Night_11_en",20413,], +["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20413,], +["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20413,], +["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20413,], +["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20413,], +["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20413,], +["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20413,], +["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20413,], ["features.messages.impl.timeline_TimelineView_Day_2_en","features.messages.impl.timeline_TimelineView_Night_2_en",0,], ["features.messages.impl.timeline_TimelineView_Day_3_en","features.messages.impl.timeline_TimelineView_Night_3_en",0,], -["features.messages.impl.timeline_TimelineView_Day_4_en","features.messages.impl.timeline_TimelineView_Night_4_en",20412,], +["features.messages.impl.timeline_TimelineView_Day_4_en","features.messages.impl.timeline_TimelineView_Night_4_en",20413,], ["features.messages.impl.timeline_TimelineView_Day_5_en","features.messages.impl.timeline_TimelineView_Night_5_en",0,], -["features.messages.impl.timeline_TimelineView_Day_6_en","features.messages.impl.timeline_TimelineView_Night_6_en",20412,], +["features.messages.impl.timeline_TimelineView_Day_6_en","features.messages.impl.timeline_TimelineView_Night_6_en",20413,], ["features.messages.impl.timeline_TimelineView_Day_7_en","features.messages.impl.timeline_TimelineView_Night_7_en",0,], -["features.messages.impl.timeline_TimelineView_Day_8_en","features.messages.impl.timeline_TimelineView_Night_8_en",20412,], +["features.messages.impl.timeline_TimelineView_Day_8_en","features.messages.impl.timeline_TimelineView_Night_8_en",20413,], ["features.messages.impl.timeline_TimelineView_Day_9_en","features.messages.impl.timeline_TimelineView_Night_9_en",0,], ["libraries.designsystem.components.avatar.internal_TombstonedRoomAvatar_Avatars_en","",0,], ["libraries.designsystem.theme.components_TopAppBarStr_App_Bars_en","",0,], ["libraries.designsystem.theme.components_TopAppBar_App_Bars_en","",0,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_0_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_0_en",20412,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20412,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20412,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20412,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20412,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20412,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20412,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20412,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_0_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_0_en",20413,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20413,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20413,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20413,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20413,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20413,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20413,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20413,], ["features.messages.impl.typing_TypingNotificationView_Day_0_en","features.messages.impl.typing_TypingNotificationView_Night_0_en",0,], -["features.messages.impl.typing_TypingNotificationView_Day_1_en","features.messages.impl.typing_TypingNotificationView_Night_1_en",20412,], -["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20412,], -["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20412,], -["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20412,], -["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20412,], -["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20412,], +["features.messages.impl.typing_TypingNotificationView_Day_1_en","features.messages.impl.typing_TypingNotificationView_Night_1_en",20413,], +["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20413,], +["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20413,], +["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20413,], +["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20413,], +["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20413,], ["features.messages.impl.typing_TypingNotificationView_Day_7_en","features.messages.impl.typing_TypingNotificationView_Night_7_en",0,], ["features.messages.impl.typing_TypingNotificationView_Day_8_en","features.messages.impl.typing_TypingNotificationView_Night_8_en",0,], ["libraries.designsystem.atomic.atoms_UnreadIndicatorAtom_Day_0_en","libraries.designsystem.atomic.atoms_UnreadIndicatorAtom_Night_0_en",0,], -["libraries.matrix.ui.components_UnresolvedUserRow_en","",20412,], +["libraries.matrix.ui.components_UnresolvedUserRow_en","",20413,], ["libraries.matrix.ui.components_UnsavedAvatar_Day_0_en","libraries.matrix.ui.components_UnsavedAvatar_Night_0_en",0,], ["libraries.designsystem.components.avatar.internal_UserAvatarColors_Day_0_en","libraries.designsystem.components.avatar.internal_UserAvatarColors_Night_0_en",0,], -["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20412,], -["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20412,], -["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20412,], -["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20412,], +["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20413,], +["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20413,], +["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20413,], +["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20413,], ["features.startchat.impl.components_UserListView_Day_3_en","features.startchat.impl.components_UserListView_Night_3_en",0,], ["features.startchat.impl.components_UserListView_Day_4_en","features.startchat.impl.components_UserListView_Night_4_en",0,], ["features.startchat.impl.components_UserListView_Day_5_en","features.startchat.impl.components_UserListView_Night_5_en",0,], ["features.startchat.impl.components_UserListView_Day_6_en","features.startchat.impl.components_UserListView_Night_6_en",0,], -["features.startchat.impl.components_UserListView_Day_7_en","features.startchat.impl.components_UserListView_Night_7_en",20412,], +["features.startchat.impl.components_UserListView_Day_7_en","features.startchat.impl.components_UserListView_Night_7_en",20413,], ["features.startchat.impl.components_UserListView_Day_8_en","features.startchat.impl.components_UserListView_Night_8_en",0,], -["features.startchat.impl.components_UserListView_Day_9_en","features.startchat.impl.components_UserListView_Night_9_en",20412,], +["features.startchat.impl.components_UserListView_Day_9_en","features.startchat.impl.components_UserListView_Night_9_en",20413,], ["features.preferences.impl.user_UserPreferences_Day_0_en","features.preferences.impl.user_UserPreferences_Night_0_en",0,], ["features.preferences.impl.user_UserPreferences_Day_1_en","features.preferences.impl.user_UserPreferences_Night_1_en",0,], ["features.preferences.impl.user_UserPreferences_Day_2_en","features.preferences.impl.user_UserPreferences_Night_2_en",0,], -["features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Day_0_en","features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Night_0_en",20412,], -["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20412,], -["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20412,], -["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20412,], -["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20412,], -["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20412,], -["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20412,], -["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20412,], -["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20412,], -["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20412,], -["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20412,], -["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20412,], +["features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Day_0_en","features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Night_0_en",20413,], +["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20413,], +["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20413,], +["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20413,], +["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20413,], +["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20413,], +["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20413,], +["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20413,], +["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20413,], +["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20413,], +["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20413,], +["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20413,], ["features.verifysession.impl.ui_VerificationUserProfileContent_Day_0_en","features.verifysession.impl.ui_VerificationUserProfileContent_Night_0_en",0,], ["libraries.designsystem.ruler_VerticalRuler_Day_0_en","libraries.designsystem.ruler_VerticalRuler_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_1_en",0,], -["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20412,], -["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20412,], +["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20413,], +["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20413,], ["features.viewfolder.impl.file_ViewFileView_Day_0_en","features.viewfolder.impl.file_ViewFileView_Night_0_en",0,], ["features.viewfolder.impl.file_ViewFileView_Day_1_en","features.viewfolder.impl.file_ViewFileView_Night_1_en",0,], ["features.viewfolder.impl.file_ViewFileView_Day_2_en","features.viewfolder.impl.file_ViewFileView_Night_2_en",0,], -["features.viewfolder.impl.file_ViewFileView_Day_3_en","features.viewfolder.impl.file_ViewFileView_Night_3_en",20412,], +["features.viewfolder.impl.file_ViewFileView_Day_3_en","features.viewfolder.impl.file_ViewFileView_Night_3_en",20413,], ["features.viewfolder.impl.file_ViewFileView_Day_4_en","features.viewfolder.impl.file_ViewFileView_Night_4_en",0,], ["features.viewfolder.impl.file_ViewFileView_Day_5_en","features.viewfolder.impl.file_ViewFileView_Night_5_en",0,], ["features.viewfolder.impl.folder_ViewFolderView_Day_0_en","features.viewfolder.impl.folder_ViewFolderView_Night_0_en",0,], diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_0_en.png index a88b62fba0..51c0e52a4a 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2f9bce15f8c83865c215539629270f233b00aa6f313433d4a4d5bae74e6584c4 -size 44262 +oid sha256:08172934ef864d57cb335b738dea8ad6f96ee2df4710c4f9d7e5adc3d110ad67 +size 44215 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_1_en.png index 842147e3f0..92584108e8 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0cd12c68415f61b198696a9f9d8b19da5e6ced287e015071a8a850100238862b -size 49992 +oid sha256:ad1fce13a5034b6db192a0735317b6cf5f10536ac05ccf1cc4996ad029ce9513 +size 49951 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_7_en.png index 601d893545..a6d1f7bb95 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:56ade704db88b09b1952df179e21c939779d7e7835424745971f16b87fc607f3 -size 24515 +oid sha256:7f509f0c857c9d2c0a23657d213ea49961bb900b652edd116c4dcf29853c7776 +size 24336 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_0_en.png index ed4e6f7c84..2b024e7b08 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:5ffd537ca46c6008cb186af649c2d83744d40d7c55bdc93a510373b85f2831e2 -size 44279 +oid sha256:bd62c76e687e342f46b792958ddd3c36d44f5c603e4ddbe79f4fd2a8e41b9750 +size 44198 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_1_en.png index ad5b94c86d..35fbc68769 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:be897269967951ea0ddb0cc209005d07d4904531a8ab9d865b6e622c9ba98e18 -size 49747 +oid sha256:cc7dd1459c04997170247296b34b9bd7953418361c2d72840d43aa159000a806 +size 49655 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_7_en.png index 50b7d88a03..f137d5539a 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:93df87720426e598912ff2715b440503124fa3b7703ebe5c58c86d816e2632a7 -size 24476 +oid sha256:bd6d96abbeda8ab8dd7804929ed205cd2c1eb8bb04d83d00a343387e93bc693b +size 24297 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en.png index b536317715..5ffb675c87 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:45c9afb0e9d60806b7fdf3b3377bf48b8a7e7976f69cb81bb5a7b7aca723b08a -size 56838 +oid sha256:b4701427ccafa8bb12a8f384433862770b84c650268772e11df91343c25bb1b0 +size 56924 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en.png index 73bf612214..f227c74f10 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c529cb7f8d705b6ec5d401fdad59befd9d2cd8391a65207a7aed4f3ad70f3553 -size 54803 +oid sha256:b307b024232c5033ab6aaf2930f244106fdb5a2bdd6c4919c24a60266fb4a814 +size 54885 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en.png index 6a53772be9..08e6c8aad9 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1227822d8dc0bda1b59570e7ea825bc5b95ce3aac8c56ba47739950a4692fe9c -size 57315 +oid sha256:aad071d4ebb05c5db831bbf75021b7dcc9de185455c7f0292d3275247bcd5b75 +size 57403 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en.png index 9f972f15bd..474c7943ff 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:08b4d5a2b0f0a9d11adb1295392ede1950c0bc3cbb7dae865e309dd301476f31 -size 57423 +oid sha256:25c09f5b840f62fc4d71b15acefb6ad73f64df7ed6e7228d0cdfd16487f1e20e +size 57503 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_9_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_9_en.png index 0f99dccd38..1dc35b3b2b 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8307cf65f832870038708f805541336dc152a2989d67d24d334ef4d774d98bd5 -size 56535 +oid sha256:53101722bdc3002df0d01827753d56cd0d47676396967b4c0d8b01fe9d048947 +size 56621 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_en.png index aebdcc6a9a..43b341d174 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cebda6fa848e04c19d3c0662e76d49ce325c5c8949d65f91fa940295ac00eaee -size 58906 +oid sha256:6d3bc2a629aceda805d0976f46c6cf9ddca8ef05123fafe5d51500d68fea5c99 +size 58981 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_en.png index 4e05cf5fcb..2ae2618dac 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:db196c0997393e76812470ee2437952ed936efac9c545820389e269a4cafd506 -size 56833 +oid sha256:518131a76d772d7b7eddbf74702e4a2a477dfea2ae9b89de58269d02820bfdca +size 56907 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_en.png index 1e08988275..afbdc3a813 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4ae1617b038bd52d66c85c0b0137f158bb30a258c806035bff9679aebe6b2875 -size 59392 +oid sha256:767c62fbb463557379dae310a4d830c0f86818ace934a25307ea3befe86042ac +size 59459 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_en.png index aa6f091f7b..52568b8670 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0478c0f3c2c0111db5815132c751dfb6b0f47f7fc117eabb3c01f5bbb213952f -size 59506 +oid sha256:b85a87cdb67b1ef8280d65e77abb77f6319a029a571a0747c4c56c2f4a652824 +size 59580 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_9_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_9_en.png index b69e9ebd09..47ebe3a1fd 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:704c6d6e29cfe0f52445e0ab28b5fd5fb138321a93a964ee9b7e2fd0c3cfa65d -size 58576 +oid sha256:083a8f10725f4573807865f02b53ca0a3c6ff2bf43d99997afa9412a547c33bd +size 58652 diff --git a/tools/localazy/config.json b/tools/localazy/config.json index 405451bb34..8cb1228b94 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -198,6 +198,7 @@ "screen_room_details_.*", "screen\\.room_details\\..*", "screen_room_member_list_.*", + "screen\\.room_member_list\\..*", "screen_room_notification_settings_.*", "screen_notification_settings_edit_failed_updating_default_mode", "screen_polls_history_title", @@ -373,7 +374,8 @@ "screen_room_change_.*", "screen_room_roles_.*", "screen\\.room_roles_and_permissions\\..*", - "screen_room_member_list.*" + "screen_room_member_list.*", + "screen\\.room_member_list\\..*" ] } ] From 1246bfa21e4e876a4f93962c3a0c6417d92b79cf Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 24 Nov 2025 20:22:11 +0100 Subject: [PATCH 044/113] deps(sdk) : add fallbackToServer on userIdentity api. --- .../matrix/api/encryption/EncryptionService.kt | 6 +++--- .../matrix/impl/encryption/RustEncryptionService.kt | 12 ++++-------- .../matrix/test/encryption/FakeEncryptionService.kt | 7 +------ 3 files changed, 8 insertions(+), 17 deletions(-) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt index 4ae75774c1..aefad517dc 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/encryption/EncryptionService.kt @@ -64,8 +64,6 @@ interface EncryptionService { */ suspend fun startIdentityReset(): Result - suspend fun isUserVerified(userId: UserId): Result - /** * Remember this identity, ensuring it does not result in a pin violation. */ @@ -82,8 +80,10 @@ interface EncryptionService { /** * Get the identity state of a user, if known. + * @param userId the user id to get the identity for. + * @param fallbackToServer whether to fallback to fetching the identity from the server if not known locally. Defaults to true. */ - suspend fun getUserIdentity(userId: UserId): Result + suspend fun getUserIdentity(userId: UserId, fallbackToServer: Boolean = true): Result } /** diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt index 6ebf80337c..e081d1c9f1 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/encryption/RustEncryptionService.kt @@ -240,10 +240,6 @@ class RustEncryptionService( } } - override suspend fun isUserVerified(userId: UserId): Result = runCatchingExceptions { - getUserIdentityInternal(userId).isVerified() - } - override suspend fun pinUserIdentity(userId: UserId): Result = runCatchingExceptions { getUserIdentityInternal(userId).pin() } @@ -252,8 +248,8 @@ class RustEncryptionService( getUserIdentityInternal(userId).withdrawVerification() } - override suspend fun getUserIdentity(userId: UserId): Result = runCatchingExceptions { - val identity = getUserIdentityInternal(userId) + override suspend fun getUserIdentity(userId: UserId, fallbackToServer: Boolean): Result = runCatchingExceptions { + val identity = getUserIdentityInternal(userId, fallbackToServer) val isVerified = identity.isVerified() when { identity.hasVerificationViolation() -> IdentityState.VerificationViolation @@ -263,10 +259,10 @@ class RustEncryptionService( } } - suspend fun getUserIdentityInternal(userId: UserId): UserIdentity { + private suspend fun getUserIdentityInternal(userId: UserId, fallbackToServer: Boolean = true): UserIdentity { return service.userIdentity( userId = userId.value, - // requestFromHomeserverIfNeeded = true, + fallbackToServer = fallbackToServer, ) ?: error("User identity not found") } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/encryption/FakeEncryptionService.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/encryption/FakeEncryptionService.kt index a94de15f1e..04e3779298 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/encryption/FakeEncryptionService.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/encryption/FakeEncryptionService.kt @@ -26,7 +26,6 @@ import kotlinx.coroutines.flow.flowOf class FakeEncryptionService( var startIdentityResetLambda: () -> Result = { lambdaError() }, private val pinUserIdentityResult: (UserId) -> Result = { lambdaError() }, - private val isUserVerifiedResult: (UserId) -> Result = { lambdaError() }, private val withdrawVerificationResult: (UserId) -> Result = { lambdaError() }, private val getUserIdentityResult: (UserId) -> Result = { lambdaError() }, private val enableRecoveryLambda: (Boolean) -> Result = { lambdaError() }, @@ -139,11 +138,7 @@ class FakeEncryptionService( return withdrawVerificationResult(userId) } - override suspend fun isUserVerified(userId: UserId): Result = simulateLongTask { - isUserVerifiedResult(userId) - } - - override suspend fun getUserIdentity(userId: UserId): Result = simulateLongTask { + override suspend fun getUserIdentity(userId: UserId, fallbackToServer: Boolean): Result = simulateLongTask { return getUserIdentityResult(userId) } From 46136aafe4e6b97aced7231265d9192b430ee720 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 24 Nov 2025 20:23:46 +0100 Subject: [PATCH 045/113] change(member list): use only local user identity --- .../roomdetails/impl/members/RoomMemberListPresenter.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt index e69ddb744a..9274c1a8e5 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt @@ -179,7 +179,7 @@ class RoomMemberListPresenter( return if (room.info().isEncrypted != true) { RoomMemberWithIdentityState(this, null) } else { - val identityState = identityStates[userId] ?: encryptionService.getUserIdentity(userId).getOrNull() + val identityState = identityStates[userId] ?: encryptionService.getUserIdentity(userId, fallbackToServer = false).getOrNull() RoomMemberWithIdentityState(this, identityState) } } From 5d6bd1edd9a6e4004fb36c115116ba3d31fb9da1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 10:28:23 +0100 Subject: [PATCH 046/113] fix(deps): update metro to v0.7.7 (#5771) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 593aaa2d70..29b5e722db 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -53,7 +53,7 @@ haze = "1.6.10" dependencyAnalysis = "3.5.0" # DI -metro = "0.7.6" +metro = "0.7.7" # Auto service autoservice = "1.1.1" From c5f636b4ef80675f18867dd28e382cec8d01ca11 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 10:37:57 +0100 Subject: [PATCH 047/113] chore(deps): update plugin sonarqube to v7.1.0.6387 (#5783) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 29b5e722db..3743d8800f 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -265,7 +265,7 @@ roborazzi = { id = "io.github.takahirom.roborazzi", version.ref = "roborazzi" } sqldelight = { id = "app.cash.sqldelight", version.ref = "sqldelight" } firebaseAppDistribution = { id = "com.google.firebase.appdistribution", version.ref = "firebaseAppDistribution" } knit = { id = "org.jetbrains.kotlinx.knit", version = "0.5.0" } -sonarqube = "org.sonarqube:7.0.1.6134" +sonarqube = "org.sonarqube:7.1.0.6387" licensee = "app.cash.licensee:1.14.1" compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" } gms_google_services = { id = "com.google.gms.google-services", version = "4.4.4" } From 1195b9a32c06106d4265c2cce4311391de064b85 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 25 Nov 2025 11:01:18 +0100 Subject: [PATCH 048/113] quality: fix test after api removal --- .../features/userprofile/impl/UserProfilePresenterTest.kt | 2 -- 1 file changed, 2 deletions(-) diff --git a/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt b/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt index 8dcf6aab20..aa984f0066 100644 --- a/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt +++ b/features/userprofile/impl/src/test/kotlin/io/element/android/features/userprofile/impl/UserProfilePresenterTest.kt @@ -386,14 +386,12 @@ class UserProfilePresenterTest { } private fun createFakeMatrixClient( - isUserVerified: Boolean = true, userIdentityState: IdentityState? = null, ignoreUserResult: (UserId) -> Result = { Result.success(Unit) }, unIgnoreUserResult: (UserId) -> Result = { Result.success(Unit) }, ignoredUsersFlow: StateFlow> = MutableStateFlow(persistentListOf()) ) = FakeMatrixClient( encryptionService = FakeEncryptionService( - isUserVerifiedResult = { Result.success(isUserVerified) }, getUserIdentityResult = { Result.success(userIdentityState) } ), ignoreUserResult = ignoreUserResult, From f3602c2d8a4de064e7a3feb5f9612a7df10c21c8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 11:17:54 +0100 Subject: [PATCH 049/113] fix(deps): update dependency io.github.sergio-sastre.composablepreviewscanner:android to v0.7.2 (#5799) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3743d8800f..86d4ef286e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -168,7 +168,7 @@ test_truth = "com.google.truth:truth:1.4.5" test_parameter_injector = "com.google.testparameterinjector:test-parameter-injector:1.19" test_robolectric = "org.robolectric:robolectric:4.15.1" test_appyx_junit = { module = "com.bumble.appyx:testing-junit4", version.ref = "appyx" } -test_composable_preview_scanner = "io.github.sergio-sastre.ComposablePreviewScanner:android:0.7.1" +test_composable_preview_scanner = "io.github.sergio-sastre.ComposablePreviewScanner:android:0.7.2" test_detekt_api = { module = "io.gitlab.arturbosch.detekt:detekt-api", version.ref = "detekt" } test_detekt_test = { module = "io.gitlab.arturbosch.detekt:detekt-test", version.ref = "detekt" } From 6a23c4a68556d5af2ba6c94e225de9dade8c9aa8 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 10:20:00 +0000 Subject: [PATCH 050/113] fix(deps): update dependency io.element.android:emojibase-bindings to v1.5.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 86d4ef286e..805046016c 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -223,7 +223,7 @@ sentry = "io.sentry:sentry-android:8.26.0" matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.29.2" # Emojibase -matrix_emojibase_bindings = "io.element.android:emojibase-bindings:1.4.3" +matrix_emojibase_bindings = "io.element.android:emojibase-bindings:1.5.0" sigpwned_emoji4j = "com.sigpwned:emoji4j-core:16.0.0" # Di From 58d0eb260ae9c214e288fc97700033947d99aa48 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 12:25:37 +0100 Subject: [PATCH 051/113] fix(deps): update dependency io.sentry:sentry-android to v8.27.1 (#5803) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 0f55838342..d711044198 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -218,7 +218,7 @@ color_picker = "io.mhssn:colorpicker:1.0.0" # Analytics posthog = "com.posthog:posthog-android:3.26.0" -sentry = "io.sentry:sentry-android:8.26.0" +sentry = "io.sentry:sentry-android:8.27.1" # main branch can be tested replacing the version with main-SNAPSHOT matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.29.2" From b7c2c4559556b4d5ef3248e71cb3f73e2697d8f6 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 25 Nov 2025 11:27:27 +0000 Subject: [PATCH 052/113] fix(deps): update roborazzi to v1.52.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index d711044198..8ba5f4112e 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -33,7 +33,7 @@ accompanist = "0.37.3" # Test test_core = "1.7.0" -roborazzi = "1.51.0" +roborazzi = "1.52.0" # Jetbrain datetime = "0.7.1" From 94c985aebb48e574ae2021ff958da3703ce3170b Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 25 Nov 2025 12:54:35 +0100 Subject: [PATCH 053/113] change(members): update tests to match new ui and logic --- .../impl/members/RoomMemberListPresenter.kt | 6 +- .../members/RoomMemberListStateProvider.kt | 187 ++++------ .../members/RoomMemberListPresenterTest.kt | 319 +++++++----------- 3 files changed, 198 insertions(+), 314 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt index 3d59b3d922..eb4735de6e 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt @@ -25,7 +25,6 @@ import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.map import io.element.android.libraries.core.coroutine.CoroutineDispatchers -import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.encryption.EncryptionService import io.element.android.libraries.matrix.api.encryption.identity.IdentityState @@ -59,9 +58,6 @@ class RoomMemberListPresenter( @Composable override fun present(): RoomMemberListState { var searchQuery by rememberSaveable { mutableStateOf("") } - var searchResults by remember { - mutableStateOf>>(SearchBarResultState.Initial()) - } val membersState by room.membersStateFlow.collectAsState() val syncUpdateFlow = room.syncUpdateFlow.collectAsState() val canInvite by room.canInviteAsState(syncUpdateFlow.value) @@ -75,8 +71,8 @@ class RoomMemberListPresenter( .launchIn(this) } - var roomMembers: AsyncData by remember { mutableStateOf(AsyncData.Loading()) } var selectedSection by remember { mutableStateOf(SelectedSection.MEMBERS) } + var roomMembers: AsyncData by remember { mutableStateOf(AsyncData.Loading()) } var filteredRoomMembers: AsyncData by remember { mutableStateOf(AsyncData.Loading()) } // Update the room members when the screen is loaded diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt index b03faa97cb..580db7667a 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListStateProvider.kt @@ -12,7 +12,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.features.roommembermoderation.api.RoomMemberModerationEvents import io.element.android.features.roommembermoderation.api.RoomMemberModerationState import io.element.android.libraries.architecture.AsyncData -import io.element.android.libraries.designsystem.theme.components.SearchBarResultState +import io.element.android.libraries.architecture.map import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.encryption.identity.IdentityState import io.element.android.libraries.matrix.api.room.RoomMember @@ -21,108 +21,59 @@ import kotlinx.collections.immutable.persistentListOf internal class RoomMemberListStateProvider : PreviewParameterProvider { override val values: Sequence - get() = roomMemberListStates() + bannedRoomMemberListStates() + get() = sequenceOf( + aRoomMemberListState( + roomMembers = AsyncData.Loading(), + selectedSection = SelectedSection.MEMBERS, + ), + aRoomMemberListState( + roomMembers = AsyncData.Failure(Exception("Error details")), + selectedSection = SelectedSection.MEMBERS, + ), + aRoomMemberListState( + roomMembers = aLoadedRoomMembers(), + selectedSection = SelectedSection.MEMBERS, + ), + aRoomMemberListState( + roomMembers = aLoadedRoomMembers(), + selectedSection = SelectedSection.BANNED, + moderationState = aRoomMemberModerationState(canBan = true), + ), + aRoomMemberListState( + roomMembers = aLoadedRoomMembers(), + canInvite = true, + selectedSection = SelectedSection.MEMBERS, + ), + aRoomMemberListState( + roomMembers = aLoadedRoomMembers(), + searchQuery = "alice", + selectedSection = SelectedSection.MEMBERS, + ), + aRoomMemberListState( + roomMembers = aLoadedRoomMembers(), + searchQuery = "something-with-no-results", + selectedSection = SelectedSection.MEMBERS, + ), + ) } -private fun roomMemberListStates(): Sequence = sequenceOf( - aRoomMemberListState( - roomMembers = AsyncData.Success( - RoomMembers( - invited = persistentListOf(aVictor().withIdentity(), aWalter().withIdentity()), - joined = persistentListOf(anAlice().withIdentity(), aBob().withIdentity(), aWalter().withIdentity()), - banned = persistentListOf(), - ), +private fun aLoadedRoomMembers() = AsyncData.Success( + RoomMembers( + invited = persistentListOf( + anInvitedVictor().withIdentity(), + anInvitedWalter().withIdentity(), ), - selectedSection = SelectedSection.MEMBERS, - ), - aRoomMemberListState( - roomMembers = AsyncData.Success( - RoomMembers( - invited = persistentListOf(aVictor().withIdentity(), aWalter().withIdentity()), - joined = persistentListOf( - anAlice().withIdentity(identityState = IdentityState.Verified), - aBob().withIdentity(identityState = IdentityState.PinViolation), - aWalter().withIdentity(identityState = IdentityState.VerificationViolation) - ), - banned = persistentListOf(), - ) + joined = persistentListOf( + anAlice().withIdentity(identityState = IdentityState.Verified), + aBob().withIdentity(identityState = IdentityState.PinViolation), + aCarol().withIdentity(), + aDavid().withIdentity(), + anEve().withIdentity(identityState = IdentityState.VerificationViolation) ), - selectedSection = SelectedSection.MEMBERS, - moderationState = aRoomMemberModerationState(canBan = true) - ), - aRoomMemberListState( - roomMembers = AsyncData.Loading(), - selectedSection = SelectedSection.MEMBERS, - ), - aRoomMemberListState().copy( - canInvite = true, - selectedSection = SelectedSection.MEMBERS, - ), - aRoomMemberListState().copy( - selectedSection = SelectedSection.MEMBERS, - ), - aRoomMemberListState().copy( - selectedSection = SelectedSection.MEMBERS, - ), - aRoomMemberListState().copy( - searchQuery = "someone", - selectedSection = SelectedSection.MEMBERS, - ), - aRoomMemberListState().copy( - searchQuery = "@someone:matrix.org", - selectedSection = SelectedSection.MEMBERS, - ), - aRoomMemberListState().copy( - searchQuery = "something-with-no-results", - selectedSection = SelectedSection.MEMBERS, - ), - aRoomMemberListState( - roomMembers = AsyncData.Failure(Exception("Error details")), - selectedSection = SelectedSection.MEMBERS, - ), -) - -private fun bannedRoomMemberListStates(): Sequence = sequenceOf( - aRoomMemberListState( - roomMembers = AsyncData.Success( - RoomMembers( - invited = persistentListOf(), - joined = persistentListOf(), - banned = persistentListOf( - aRoomMember(userId = UserId("@alice:example.com"), displayName = "Alice").withIdentity(), - aRoomMember(userId = UserId("@bob:example.com"), displayName = "Bob").withIdentity(), - aRoomMember(userId = UserId("@charlie:example.com"), displayName = "Charlie").withIdentity(), - ), - ) + banned = persistentListOf( + aBannedMallory().withIdentity(), + aBannedSusie().withIdentity() ), - moderationState = aRoomMemberModerationState(), - selectedSection = SelectedSection.BANNED, - ), - aRoomMemberListState( - roomMembers = AsyncData.Loading( - RoomMembers( - invited = persistentListOf(), - joined = persistentListOf(), - banned = persistentListOf( - aRoomMember(userId = UserId("@alice:example.com"), displayName = "Alice").withIdentity(), - aRoomMember(userId = UserId("@bob:example.com"), displayName = "Bob").withIdentity(), - aRoomMember(userId = UserId("@charlie:example.com"), displayName = "Charlie").withIdentity(), - ), - ) - ), - moderationState = aRoomMemberModerationState(), - selectedSection = SelectedSection.BANNED, - ), - aRoomMemberListState( - roomMembers = AsyncData.Success( - RoomMembers( - invited = persistentListOf(), - joined = persistentListOf(), - banned = persistentListOf(), - ) - ), - moderationState = aRoomMemberModerationState(), - selectedSection = SelectedSection.BANNED, ) ) @@ -130,14 +81,17 @@ internal fun aRoomMemberListState( roomMembers: AsyncData = AsyncData.Loading(), moderationState: RoomMemberModerationState = aRoomMemberModerationState(), selectedSection: SelectedSection = SelectedSection.MEMBERS, + searchQuery: String = "", + canInvite: Boolean = false, + eventSink: (RoomMemberListEvents) -> Unit = {}, ) = RoomMemberListState( roomMembers = roomMembers, - filteredRoomMembers = roomMembers, - searchQuery = "", - canInvite = false, + filteredRoomMembers = roomMembers.map { it.filter(searchQuery) }, + searchQuery = searchQuery, + canInvite = canInvite, moderationState = moderationState, selectedSection = selectedSection, - eventSink = {} + eventSink = eventSink ) fun aRoomMemberModerationState( @@ -176,21 +130,30 @@ fun aRoomMember( fun aRoomMemberList() = persistentListOf( anAlice(), aBob(), - aRoomMember(UserId("@carol:server.org"), "Carol"), - aRoomMember(UserId("@david:server.org"), "David"), - aRoomMember(UserId("@eve:server.org"), "Eve"), - aRoomMember(UserId("@justin:server.org"), "Justin"), - aRoomMember(UserId("@mallory:server.org"), "Mallory"), - aRoomMember(UserId("@susie:server.org"), "Susie"), - aVictor(), - aWalter(), + aCarol(), + aDavid(), + anEve(), + anInvitedVictor(), + anInvitedWalter(), + aBannedSusie(), + aBannedMallory(), ) +fun anEve(): RoomMember = aRoomMember(UserId("@eve:server.org"), "Eve") + +fun aDavid(): RoomMember = aRoomMember(UserId("@david:server.org"), "David") + +fun aCarol(): RoomMember = aRoomMember(UserId("@carol:server.org"), "Carol") + fun anAlice() = aRoomMember(UserId("@alice:server.org"), "Alice", role = RoomMember.Role.Admin) fun aBob() = aRoomMember(UserId("@bob:server.org"), "Bob", role = RoomMember.Role.Moderator) -fun aVictor() = aRoomMember(UserId("@victor:server.org"), "Victor", membership = RoomMembershipState.INVITE) +fun anInvitedVictor() = aRoomMember(UserId("@victor:server.org"), "Victor", membership = RoomMembershipState.INVITE) -fun aWalter() = aRoomMember(UserId("@walter:server.org"), "Walter", membership = RoomMembershipState.INVITE) +fun anInvitedWalter() = aRoomMember(UserId("@walter:server.org"), "Walter", membership = RoomMembershipState.INVITE) + +fun aBannedSusie(): RoomMember = aRoomMember(UserId("@susie:server.org"), "Susie", membership = RoomMembershipState.BAN) + +fun aBannedMallory(): RoomMember = aRoomMember(UserId("@mallory:server.org"), "Mallory", membership = RoomMembershipState.BAN) private fun RoomMember.withIdentity(identityState: IdentityState? = null) = RoomMemberWithIdentityState(this, identityState) diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt index 3c0fe34366..1548feae88 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt @@ -8,36 +8,27 @@ package io.element.android.features.roomdetails.impl.members -import app.cash.molecule.RecompositionMode -import app.cash.molecule.moleculeFlow -import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.features.roommembermoderation.api.RoomMemberModerationState import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.coroutine.CoroutineDispatchers -import io.element.android.libraries.designsystem.theme.components.SearchBarResultState -import io.element.android.libraries.matrix.api.room.BaseRoom +import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.room.RoomMembersState +import io.element.android.libraries.matrix.api.room.RoomMembershipState import io.element.android.libraries.matrix.test.encryption.FakeEncryptionService import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.tests.testutils.WarmUpRule -import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.test import io.element.android.tests.testutils.testCoroutineDispatchers -import kotlinx.collections.immutable.persistentListOf +import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.launch -import kotlinx.coroutines.sync.Mutex -import kotlinx.coroutines.sync.withLock import kotlinx.coroutines.test.TestScope import kotlinx.coroutines.test.runTest -import kotlinx.coroutines.time.withTimeout -import kotlinx.coroutines.withTimeout import org.junit.Rule import org.junit.Test -import kotlin.time.Duration.Companion.seconds @ExperimentalCoroutinesApi class RoomMemberListPresenterTest { @@ -45,176 +36,132 @@ class RoomMemberListPresenterTest { val warmUpRule = WarmUpRule() @Test - fun `member loading is done automatically on start, but is async`() = runTest { - val room = FakeJoinedRoom( - baseRoom = FakeBaseRoom( - updateMembersResult = { Result.success(Unit) }, - canInviteResult = { Result.success(true) } - ).apply { - // Needed to avoid discarding the loaded members as a partial and invalid result - givenRoomInfo(aRoomInfo(joinedMembersCount = 2)) - } - ) - val presenter = createPresenter(joinedRoom = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + fun `initial state is loading`() = runTest { + val presenter = createPresenter() + presenter.test { skipItems(1) val initialState = awaitItem() - assertThat(initialState.roomMembers.isLoading()).isTrue() + assertThat(initialState.filteredRoomMembers.isLoading()).isTrue() assertThat(initialState.searchQuery).isEmpty() - assertThat(initialState.searchResults).isInstanceOf(SearchBarResultState.Initial::class.java) - assertThat(initialState.isSearchActive).isFalse() - room.givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) - // Skip item while the new members state is processed - skipItems(1) - val loadedMembersState = awaitItem() - assertThat(loadedMembersState.roomMembers.isLoading()).isFalse() - assertThat(loadedMembersState.roomMembers.dataOrNull()?.invited) - .isEqualTo(listOf(RoomMemberWithIdentityState(aVictor(), null), RoomMemberWithIdentityState(aWalter(), null))) - assertThat(loadedMembersState.roomMembers.dataOrNull()?.joined).isNotEmpty() + assertThat(initialState.selectedSection).isEqualTo(SelectedSection.MEMBERS) } } @Test - fun `member loading is done automatically when RoomInfo's activeMemberCount changes`() = runTest { - val reloadMembersMutex = Mutex() - val updateMembersLambda = lambdaRecorder { - if (reloadMembersMutex.isLocked) { - reloadMembersMutex.unlock() + fun `hide banned section when there is no banned users`() = runTest { + val allRoomMembers = aRoomMemberList() + val noBannedMembers = allRoomMembers + .filterNot { it.membership == RoomMembershipState.BAN } + .toImmutableList() + val room = createFakeJoinedRoom() + .apply { + givenRoomMembersState(RoomMembersState.Ready(allRoomMembers)) } - } - val room = FakeJoinedRoom( - baseRoom = FakeBaseRoom( - updateMembersResult = updateMembersLambda, - canInviteResult = { Result.success(true) } - ).apply { - // Needed to avoid discarding the loaded members as a partial and invalid result - givenRoomInfo(aRoomInfo(joinedMembersCount = 2)) - } - ) - val presenter = createPresenter(joinedRoom = room) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - skipItems(1) - val initialState = awaitItem() - assertThat(initialState.roomMembers.isLoading()).isTrue() - room.givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) - // Skip item while the new members state is processed - skipItems(1) - val loadedMembersState = awaitItem() - assertThat(loadedMembersState.roomMembers.isLoading()).isFalse() - assertThat(loadedMembersState.roomMembers.dataOrNull()?.joined).isNotEmpty() - - // Assert no events are emitted only with that change - expectNoEvents() - - // This will only progress if the `Room.updateMembers()` function is called, triggered by the RoomInfo change - withTimeout(10.seconds) { - reloadMembersMutex.withLock { - launch { room.givenRoomInfo(aRoomInfo(activeMembersCount = 0L)) } - } - } - - // Update the room members state as `Room.updateMembers()` would have done with the actual implementation - room.givenRoomMembersState(RoomMembersState.Ready(persistentListOf())) - // Wait for another update - skipItems(1) - // The members should be reloaded now - assertThat(awaitItem().roomMembers.dataOrNull()?.joined).isEmpty() - } - } - - @Test - fun `open search`() = runTest { val presenter = createPresenter( - joinedRoom = FakeJoinedRoom( - baseRoom = FakeBaseRoom( - updateMembersResult = { Result.success(Unit) }, - canInviteResult = { Result.success(true) } - ) - ) + joinedRoom = room, + roomMemberModerationState = aRoomMemberModerationState(canBan = true), ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) val loadedState = awaitItem() - loadedState.eventSink(RoomMemberListEvents.OnSearchActiveChanged(true)) + assertThat(loadedState.showBannedSection).isTrue() + loadedState.eventSink(RoomMemberListEvents.ChangeSelectedSection(SelectedSection.BANNED)) + val bannedSectionState = awaitItem() + assertThat(bannedSectionState.selectedSection).isEqualTo(SelectedSection.BANNED) + // Now update the room members to have no banned users + room.givenRoomMembersState(RoomMembersState.Ready(noBannedMembers)) skipItems(1) - val searchActiveState = awaitItem() - assertThat(searchActiveState.isSearchActive).isTrue() + val noBannedMembersState = awaitItem() + assertThat(noBannedMembersState.showBannedSection).isFalse() + skipItems(1) + val finalState = awaitItem() + assertThat(finalState.selectedSection).isEqualTo(SelectedSection.MEMBERS) + } + + } + + @Test + fun `member loading is done automatically on start, but is async`() = runTest { + val room = createFakeJoinedRoom() + val presenter = createPresenter(joinedRoom = room) + presenter.test { + skipItems(1) + val initialState = awaitItem() + assertThat(initialState.filteredRoomMembers.isLoading()).isTrue() + assertThat(initialState.searchQuery).isEmpty() + room.givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) + // Skip items while the new members state is processed + skipItems(2) + val loadedState = awaitItem() + val loadedRoomMembers = loadedState.filteredRoomMembers.dataOrNull()!! + assertThat(loadedRoomMembers.joined).isNotEmpty() + assertThat(loadedRoomMembers.banned).isNotEmpty() + assertThat(loadedRoomMembers.invited).isNotEmpty() + assertThat(loadedRoomMembers.isEmpty(SelectedSection.MEMBERS)).isFalse() + assertThat(loadedRoomMembers.isEmpty(SelectedSection.BANNED)).isFalse() } } @Test fun `search for something which is not found`() = runTest { - val presenter = createPresenter( - joinedRoom = FakeJoinedRoom( - baseRoom = FakeBaseRoom( - updateMembersResult = { Result.success(Unit) }, - canInviteResult = { Result.success(true) } - ) - ) - ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + val room = createFakeJoinedRoom().apply { + givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) + } + val presenter = createPresenter(joinedRoom = room) + presenter.test { skipItems(1) val loadedState = awaitItem() - loadedState.eventSink(RoomMemberListEvents.OnSearchActiveChanged(true)) - val searchActiveState = awaitItem() - searchActiveState.eventSink(RoomMemberListEvents.UpdateSearchQuery("something")) - skipItems(1) + val loadedRoomMembers = loadedState.filteredRoomMembers.dataOrNull()!! + assertThat(loadedRoomMembers.joined).isNotEmpty() + assertThat(loadedRoomMembers.banned).isNotEmpty() + assertThat(loadedRoomMembers.invited).isNotEmpty() + assertThat(loadedRoomMembers.isEmpty(SelectedSection.MEMBERS)).isFalse() + assertThat(loadedRoomMembers.isEmpty(SelectedSection.BANNED)).isFalse() + loadedState.eventSink(RoomMemberListEvents.UpdateSearchQuery("something")) val searchQueryUpdatedState = awaitItem() assertThat(searchQueryUpdatedState.searchQuery).isEqualTo("something") val searchSearchResultDelivered = awaitItem() - assertThat(searchSearchResultDelivered.searchResults).isInstanceOf(SearchBarResultState.NoResultsFound::class.java) + val emptyRoomMembers = searchSearchResultDelivered.filteredRoomMembers.dataOrNull()!! + assertThat(emptyRoomMembers.joined).isEmpty() + assertThat(emptyRoomMembers.banned).isEmpty() + assertThat(emptyRoomMembers.invited).isEmpty() + assertThat(emptyRoomMembers.isEmpty(SelectedSection.MEMBERS)).isTrue() + assertThat(emptyRoomMembers.isEmpty(SelectedSection.BANNED)).isTrue() } } @Test fun `search for something which is found`() = runTest { - val presenter = createPresenter( - joinedRoom = FakeJoinedRoom( - baseRoom = FakeBaseRoom( - updateMembersResult = { Result.success(Unit) }, - canInviteResult = { Result.success(true) } - ) - ) - ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + val room = createFakeJoinedRoom().apply { + givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) + } + val presenter = createPresenter(joinedRoom = room) + presenter.test { skipItems(1) val loadedState = awaitItem() - loadedState.eventSink(RoomMemberListEvents.OnSearchActiveChanged(true)) - val searchActiveState = awaitItem() - searchActiveState.eventSink(RoomMemberListEvents.UpdateSearchQuery("Alice")) - skipItems(1) + val loadedRoomMembers = loadedState.filteredRoomMembers.dataOrNull()!! + assertThat(loadedRoomMembers.joined).isNotEmpty() + assertThat(loadedRoomMembers.banned).isNotEmpty() + assertThat(loadedRoomMembers.invited).isNotEmpty() + assertThat(loadedRoomMembers.isEmpty(SelectedSection.MEMBERS)).isFalse() + assertThat(loadedRoomMembers.isEmpty(SelectedSection.BANNED)).isFalse() + loadedState.eventSink(RoomMemberListEvents.UpdateSearchQuery("alice")) val searchQueryUpdatedState = awaitItem() - assertThat(searchQueryUpdatedState.searchQuery).isEqualTo("Alice") + assertThat(searchQueryUpdatedState.searchQuery).isEqualTo("alice") val searchSearchResultDelivered = awaitItem() - assertThat(searchSearchResultDelivered.searchResults).isInstanceOf(SearchBarResultState.Results::class.java) - assertThat((searchSearchResultDelivered.searchResults as SearchBarResultState.Results).results.dataOrNull()!!.joined.first().roomMember.displayName) - .isEqualTo("Alice") + val emptyRoomMembers = searchSearchResultDelivered.filteredRoomMembers.dataOrNull()!! + assertThat(emptyRoomMembers.joined).isNotEmpty() + assertThat(emptyRoomMembers.banned).isEmpty() + assertThat(emptyRoomMembers.invited).isEmpty() + assertThat(emptyRoomMembers.isEmpty(SelectedSection.MEMBERS)).isFalse() + assertThat(emptyRoomMembers.isEmpty(SelectedSection.BANNED)).isTrue() } } @Test fun `present - asynchronously sets canInvite when user has correct power level`() = runTest { - val presenter = createPresenter( - joinedRoom = FakeJoinedRoom( - baseRoom = FakeBaseRoom( - canInviteResult = { Result.success(true) }, - updateMembersResult = { Result.success(Unit) } - ) - ) - ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + val presenter = createPresenter() + presenter.test { skipItems(1) val loadedState = awaitItem() assertThat(loadedState.canInvite).isTrue() @@ -224,17 +171,11 @@ class RoomMemberListPresenterTest { @Test fun `present - asynchronously sets canInvite when user does not have correct power level`() = runTest { val presenter = createPresenter( - joinedRoom = FakeJoinedRoom( - baseRoom = FakeBaseRoom( - canInviteResult = { Result.success(false) }, - updateMembersResult = { Result.success(Unit) } - ) + joinedRoom = createFakeJoinedRoom( + canInviteResult = { Result.success(false) }, ) ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - skipItems(1) + presenter.test { val loadedState = awaitItem() assertThat(loadedState.canInvite).isFalse() } @@ -243,70 +184,54 @@ class RoomMemberListPresenterTest { @Test fun `present - asynchronously sets canInvite when power level check fails`() = runTest { val presenter = createPresenter( - joinedRoom = FakeJoinedRoom( - baseRoom = FakeBaseRoom( - canInviteResult = { Result.failure(RuntimeException("Eek")) }, - updateMembersResult = { Result.success(Unit) } - ) + joinedRoom = createFakeJoinedRoom( + canInviteResult = { Result.failure(RuntimeException("Eek")) }, ) ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { - skipItems(1) + presenter.test { val loadedState = awaitItem() assertThat(loadedState.canInvite).isFalse() } } @Test - fun `present - RoomMemberSelected will open the moderation options when target user is not banned`() = runTest { - val roomMemberModerationPresenter = Presenter { - aRoomMemberModerationState(canBan = true, canKick = true) - } + fun `present - RoomMemberSelected will open the moderation options`() = runTest { val presenter = createPresenter( - roomMemberModerationPresenter = roomMemberModerationPresenter, - joinedRoom = FakeJoinedRoom( - baseRoom = FakeBaseRoom( - updateMembersResult = { Result.success(Unit) }, - canInviteResult = { Result.success(true) } - ) - ) + roomMemberModerationState = aRoomMemberModerationState(canBan = true, canKick = true) ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { skipItems(1) - awaitItem().eventSink(RoomMemberListEvents.RoomMemberSelected(aVictor())) + awaitItem().eventSink(RoomMemberListEvents.RoomMemberSelected(anInvitedVictor())) } } } -@ExperimentalCoroutinesApi -private fun TestScope.createDataSource( - room: BaseRoom = FakeBaseRoom().apply { - givenRoomMembersState(RoomMembersState.Ready(aRoomMemberList())) - }, - coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers() -) = RoomMemberListDataSource(room, coroutineDispatchers) +private fun createFakeJoinedRoom( + updateMembersResult: () -> Unit = { }, + canInviteResult: (UserId) -> Result = { Result.success(true) }, +): FakeJoinedRoom { + return FakeJoinedRoom( + baseRoom = FakeBaseRoom( + updateMembersResult = updateMembersResult, + canInviteResult = canInviteResult, + ).apply { + // Needed to avoid discarding the loaded members as a partial and invalid result + givenRoomInfo(aRoomInfo(joinedMembersCount = 2)) + } + ) +} @ExperimentalCoroutinesApi private fun TestScope.createPresenter( coroutineDispatchers: CoroutineDispatchers = testCoroutineDispatchers(useUnconfinedTestDispatcher = true), - joinedRoom: JoinedRoom = FakeJoinedRoom( - baseRoom = FakeBaseRoom( - updateMembersResult = { Result.success(Unit) } - ) - ), - roomMemberListDataSource: RoomMemberListDataSource = createDataSource(coroutineDispatchers = coroutineDispatchers), + joinedRoom: JoinedRoom = createFakeJoinedRoom(), encryptedService: FakeEncryptionService = FakeEncryptionService(), - roomMemberModerationPresenter: Presenter = Presenter { - aRoomMemberModerationState() - }, + roomMemberModerationState: RoomMemberModerationState = aRoomMemberModerationState(), ) = RoomMemberListPresenter( room = joinedRoom, - roomMemberListDataSource = roomMemberListDataSource, coroutineDispatchers = coroutineDispatchers, - roomMembersModerationPresenter = roomMemberModerationPresenter, + roomMembersModerationPresenter = Presenter { + roomMemberModerationState + }, encryptionService = encryptedService, ) From 6467912c69ccc1b30af192e955d3af1e17517706 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 25 Nov 2025 14:30:59 +0100 Subject: [PATCH 054/113] quality: fix warnings --- .../roomdetails/impl/members/RoomMemberListEvents.kt | 2 +- .../roomdetails/impl/members/RoomMemberListPresenter.kt | 1 - .../features/roomdetails/impl/members/RoomMemberListView.kt | 6 ------ .../roomdetails/impl/members/RoomMemberListPresenterTest.kt | 1 - .../io/element/android/tests/konsist/KonsistPreviewTest.kt | 1 - 5 files changed, 1 insertion(+), 10 deletions(-) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt index a4b7b22bf3..ec1b130b3e 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListEvents.kt @@ -11,7 +11,7 @@ package io.element.android.features.roomdetails.impl.members import io.element.android.libraries.matrix.api.room.RoomMember sealed interface RoomMemberListEvents { - data class ChangeSelectedSection(val section: SelectedSection): RoomMemberListEvents + data class ChangeSelectedSection(val section: SelectedSection) : RoomMemberListEvents data class UpdateSearchQuery(val query: String) : RoomMemberListEvents data class RoomMemberSelected(val roomMember: RoomMember) : RoomMemberListEvents } diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt index 90d85fac4b..f1d3f61f7e 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenter.kt @@ -52,7 +52,6 @@ class RoomMemberListPresenter( private val roomMembersModerationPresenter: Presenter, private val encryptionService: EncryptionService, ) : Presenter { - private val powerLevelRoomMemberComparator = PowerLevelRoomMemberComparator() @Composable diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt index d5a161b898..7c83f74f00 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListView.kt @@ -9,12 +9,6 @@ package io.element.android.features.roomdetails.impl.members import androidx.compose.animation.AnimatedVisibility -import androidx.compose.animation.expandHorizontally -import androidx.compose.animation.expandVertically -import androidx.compose.animation.fadeIn -import androidx.compose.animation.fadeOut -import androidx.compose.animation.shrinkHorizontally -import androidx.compose.animation.shrinkVertically import androidx.compose.foundation.background import androidx.compose.foundation.clickable import androidx.compose.foundation.layout.Arrangement diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt index 1548feae88..8d3d0e35e3 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/members/RoomMemberListPresenterTest.kt @@ -77,7 +77,6 @@ class RoomMemberListPresenterTest { val finalState = awaitItem() assertThat(finalState.selectedSection).isEqualTo(SelectedSection.MEMBERS) } - } @Test diff --git a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt index 4fbf8773db..b4f15d8d96 100644 --- a/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt +++ b/tests/konsist/src/test/kotlin/io/element/android/tests/konsist/KonsistPreviewTest.kt @@ -116,7 +116,6 @@ class KonsistPreviewTest { "ProgressDialogWithContentPreview", "ProgressDialogWithTextAndContentPreview", "ReadReceiptBottomSheetPreview", - "RoomMemberListViewBannedPreview", "SasEmojisPreview", "SecureBackupSetupViewChangePreview", "SelectedUserCannotRemovePreview", From 3240dbf2a92df7a48dc80d940db781cc6c4e8cba Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 25 Nov 2025 13:45:55 +0000 Subject: [PATCH 055/113] Update screenshots --- ...details.impl.members_RoomMemberListViewBanned_Day_0_en.png | 3 --- ...details.impl.members_RoomMemberListViewBanned_Day_1_en.png | 3 --- ...details.impl.members_RoomMemberListViewBanned_Day_2_en.png | 3 --- ...tails.impl.members_RoomMemberListViewBanned_Night_0_en.png | 3 --- ...tails.impl.members_RoomMemberListViewBanned_Night_1_en.png | 3 --- ...tails.impl.members_RoomMemberListViewBanned_Night_2_en.png | 3 --- ...s.roomdetails.impl.members_RoomMemberListView_Day_0_en.png | 4 ++-- ...s.roomdetails.impl.members_RoomMemberListView_Day_1_en.png | 4 ++-- ...s.roomdetails.impl.members_RoomMemberListView_Day_2_en.png | 4 ++-- ...s.roomdetails.impl.members_RoomMemberListView_Day_3_en.png | 4 ++-- ...s.roomdetails.impl.members_RoomMemberListView_Day_4_en.png | 4 ++-- ...s.roomdetails.impl.members_RoomMemberListView_Day_5_en.png | 4 ++-- ...s.roomdetails.impl.members_RoomMemberListView_Day_6_en.png | 4 ++-- ...s.roomdetails.impl.members_RoomMemberListView_Day_7_en.png | 3 --- ...s.roomdetails.impl.members_RoomMemberListView_Day_8_en.png | 3 --- ...s.roomdetails.impl.members_RoomMemberListView_Day_9_en.png | 3 --- ...roomdetails.impl.members_RoomMemberListView_Night_0_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_1_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_2_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_3_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_4_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_5_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_6_en.png | 4 ++-- ...roomdetails.impl.members_RoomMemberListView_Night_7_en.png | 3 --- ...roomdetails.impl.members_RoomMemberListView_Night_8_en.png | 3 --- ...roomdetails.impl.members_RoomMemberListView_Night_9_en.png | 3 --- ...embermoderation.impl_RoomMemberModerationView_Day_0_en.png | 4 ++-- ...embermoderation.impl_RoomMemberModerationView_Day_1_en.png | 4 ++-- ...embermoderation.impl_RoomMemberModerationView_Day_2_en.png | 4 ++-- ...embermoderation.impl_RoomMemberModerationView_Day_3_en.png | 4 ++-- ...bermoderation.impl_RoomMemberModerationView_Night_0_en.png | 4 ++-- ...bermoderation.impl_RoomMemberModerationView_Night_1_en.png | 4 ++-- ...bermoderation.impl_RoomMemberModerationView_Night_2_en.png | 4 ++-- ...bermoderation.impl_RoomMemberModerationView_Night_3_en.png | 4 ++-- ...stem.theme.components_SearchFieldsDark_Search_views_en.png | 3 +++ ...tem.theme.components_SearchFieldsLight_Search_views_en.png | 3 +++ 36 files changed, 50 insertions(+), 80 deletions(-) delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Night_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Night_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Night_2_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_7_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_8_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_9_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_7_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_8_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_9_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchFieldsDark_Search_views_en.png create mode 100644 tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchFieldsLight_Search_views_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_en.png deleted file mode 100644 index eeca901e19..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5070188463df330ea8f7969228f436dba0db5dd9eb9280f5b4484296176bf3e9 -size 11503 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_en.png deleted file mode 100644 index f2cf45bfff..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4f544e2018c0cd221e6bba338e61af4f306809d10d37bd5b20c33e0fa67cbabb -size 11741 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_en.png deleted file mode 100644 index eeca901e19..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:5070188463df330ea8f7969228f436dba0db5dd9eb9280f5b4484296176bf3e9 -size 11503 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Night_0_en.png deleted file mode 100644 index 1a42b8c5b7..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Night_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:07dc1c12e55e3eb3ce6ee01582535641a08d62d4b059bdd581af6c58063ca70c -size 10849 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Night_1_en.png deleted file mode 100644 index 05a92bcc05..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Night_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:1fe0b9379ed8bd9a3c19c7cff5eb6085657e1453e4f8d6ebe88a3338e738236c -size 11067 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Night_2_en.png deleted file mode 100644 index 1a42b8c5b7..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListViewBanned_Night_2_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:07dc1c12e55e3eb3ce6ee01582535641a08d62d4b059bdd581af6c58063ca70c -size 10849 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_0_en.png index 51c0e52a4a..0a2320e58a 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:08172934ef864d57cb335b738dea8ad6f96ee2df4710c4f9d7e5adc3d110ad67 -size 44215 +oid sha256:367bc0df8b1839af2b434de55ea3815af4a8c112cc96e98ee76c3b9a4949fe52 +size 12985 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_1_en.png index 92584108e8..96ed928dbd 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ad1fce13a5034b6db192a0735317b6cf5f10536ac05ccf1cc4996ad029ce9513 -size 49951 +oid sha256:1700a0f9e6f9115015849c900d7faa27f70fa29752bde7666eeb36cf4eb1a6da +size 19463 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_2_en.png index f2cf45bfff..c4d6e129cd 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4f544e2018c0cd221e6bba338e61af4f306809d10d37bd5b20c33e0fa67cbabb -size 11741 +oid sha256:c8b5970490e96a693655df832f9c4bf83dd55a8b06da27b48881d9f61b2dfd9c +size 55110 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_3_en.png index 129f9d3f0d..6ac0644c32 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cad1aae139861f1ba83d3b03a6d78916c2ced5f19e6e99b935b4a49c1b5d12bb -size 12686 +oid sha256:bae192229d384047dcf5fb6744267a9e448d7f0a4f933a4984a0d1c3b9d07da2 +size 30789 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_4_en.png index f2cf45bfff..eff729cb56 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4f544e2018c0cd221e6bba338e61af4f306809d10d37bd5b20c33e0fa67cbabb -size 11741 +oid sha256:6b7049a6865a0ea4529cc43d16a27b9107e26d6583f429affe8327840b84ac2a +size 56050 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_5_en.png index f653c35d7b..83c58ce783 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:fd50f1d35f872ee93bd6b2aff1feaffcc2314b11fae60302351f738bd86d735c -size 7630 +oid sha256:0b4a208d39a5f6040d17da5290a8f2f81cd917aa02c8e38b092fc79497e1e563 +size 18394 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_6_en.png index afa0af99d4..e75132eece 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:8c0c23f8cb90609cc1f6107f4d34efbc044de92286cb237487993953f5497e5e -size 6521 +oid sha256:acfaec83e840845137f9c07d1325e24f106bc67ccdbf6c548e77efe1d490596b +size 29428 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_7_en.png deleted file mode 100644 index a6d1f7bb95..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_7_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:7f509f0c857c9d2c0a23657d213ea49961bb900b652edd116c4dcf29853c7776 -size 24336 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_8_en.png deleted file mode 100644 index 9df1642c6b..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_8_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:58d4c3e636f71ac1408189c3c14da3b0dd1e700a1be02a02f373adbcb5604b48 -size 10976 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_9_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_9_en.png deleted file mode 100644 index 42bcea1374..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Day_9_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cba49da736f96c2dd8ca3822e796930f4bd6ff3497b72f394d034147178906ce -size 18239 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_0_en.png index 2b024e7b08..aa53274f42 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bd62c76e687e342f46b792958ddd3c36d44f5c603e4ddbe79f4fd2a8e41b9750 -size 44198 +oid sha256:7b01cfde0e59d64a9e6d576e22e2ac9eeab5ab1a99cb0f9f54d1c8cec80ac4bd +size 12154 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_1_en.png index 35fbc68769..56cecab8e5 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:cc7dd1459c04997170247296b34b9bd7953418361c2d72840d43aa159000a806 -size 49655 +oid sha256:2cb19c23879eb9698729561fb1ef79c1e65a36eab0f24681e4cf72dfdde45d04 +size 18281 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_2_en.png index 05a92bcc05..d4d2263960 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1fe0b9379ed8bd9a3c19c7cff5eb6085657e1453e4f8d6ebe88a3338e738236c -size 11067 +oid sha256:889734242ce96bfc206ae1421ab9c1cbccbcb11f99889445ea27833cbd057a0a +size 55231 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_3_en.png index 31ebaceceb..c313f14d52 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:34198a1ba6c0f6385eb8732d36622ee0d6f865c72085d95d378d82ed7afe9486 -size 11936 +oid sha256:dc20039c1c5d456f318f22e524360d411d4a4980b6a2a9312c0707c0fe865340 +size 29867 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_4_en.png index 05a92bcc05..dcd18cf977 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1fe0b9379ed8bd9a3c19c7cff5eb6085657e1453e4f8d6ebe88a3338e738236c -size 11067 +oid sha256:5bb86c6fea38d0e798cffa5fee0610a32048aeb1d3427cd9b5b749dfacee0e55 +size 56063 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_5_en.png index c002b74577..612b340865 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:11c23632578610a78a6700f9d103ff6b4b3da03887cfb1918b10f2c6052e6820 -size 7549 +oid sha256:a6d55832abbcffc4d84b7139fbfb19d4c96a5ebcc9233ff139c5aae6b9f406d9 +size 17831 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_6_en.png index 775f637648..8b06d03eed 100644 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b838359a59cdc357f0ef80d701f6093ea45875c7915ba438901748f43ce9106b -size 6316 +oid sha256:3802b661c6fc656f621ba3c368eeb93f004561b01926faa572c4ba5ee66d07eb +size 28474 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_7_en.png deleted file mode 100644 index f137d5539a..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_7_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:bd6d96abbeda8ab8dd7804929ed205cd2c1eb8bb04d83d00a343387e93bc693b -size 24297 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_8_en.png deleted file mode 100644 index 8aa1b22c1d..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_8_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ced65352d0aee02e92f19fc890a8fa92efabfb8255a9a58e36dc539e2d4d6009 -size 10664 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_9_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_9_en.png deleted file mode 100644 index 083ca54d13..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.members_RoomMemberListView_Night_9_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:d9f910e14188c705d993201bdebab2f818badc71272195aa4cce31728315beea -size 17207 diff --git a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en.png index 8c46960350..95a89c2a78 100644 --- a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:54e526b8ab19ec121349dfc61f751b4d301c61ec47f1c1ec1c02d120b1f4faaf -size 17064 +oid sha256:f333d59f48ec9ff036e72c727c3bfae32dbb919c35b854906fca153bfc1c84e4 +size 17375 diff --git a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en.png index 20f1127aec..a99bf703be 100644 --- a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1be3ac8e92243baeceeb7349ed767e4c39ebfc4880b253e7f2e46ed9fc75da01 -size 20222 +oid sha256:dd83d242f9099de1ae0c84b07cb773e08dde1ae535ee2fd2bcb002e2e0e22132 +size 20397 diff --git a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en.png index 241888f87a..ea3e995ea4 100644 --- a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4e8c820a8c4966526e7851b4f3152ccaf9072bbf8ebf21737d35d1c87325bf6f -size 22524 +oid sha256:0f3d63a5c888eb1b951be3c46c4c51f7c622d7e7838c35b3de388ac1cd20789d +size 22793 diff --git a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en.png index 5f0d9f5308..b23185f4fb 100644 --- a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:983e163f59ef03f5a7c30cf7073002105a663cec64f8a8d4fc89fa0991bfd730 -size 22646 +oid sha256:e5ce9706fbc30f9d99c35c9d1f145c7f933295fe3eb62063c640b303526649db +size 22915 diff --git a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en.png index bdfffdde8c..608faed7c0 100644 --- a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:6db6ff988fd128f537764e5a3fcaa94e67db3057fc7030698adabe70f962c1b4 -size 15991 +oid sha256:06aad1478e9096e5215bd3116a7bef0e98037383c835de73f57d46a9cfa86137 +size 16415 diff --git a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en.png index 0920ebc642..d1328d932a 100644 --- a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e4868e2ce56debe8b175715417190db0037d59d204a28b5c0bc0b0c81a5d91a9 -size 18925 +oid sha256:71cd9c85c33cc222836ec26f39e7209a954728d5beebadf53a784bd5a0813709 +size 19390 diff --git a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en.png index f888174764..b4c1e1cbee 100644 --- a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a59481d4391dd8d0cb749ff63d3bb34846b450a6713ade11a6dbbe0461bb3650 -size 21257 +oid sha256:66b527092681543f600725e508213f59524b5bdf3f3ceff2bbc47d43cc9d66e8 +size 21685 diff --git a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en.png index d2ee835a9f..1b47b493b4 100644 --- a/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:381fbeb4b57f044fb785b65d04b041c4ca5efa89138742b8480a7540ed57b4f0 -size 21335 +oid sha256:47c1592948df21f0f3d69dead320f50e47ebf8da3bb86bc8302ad392d5813c57 +size 21765 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchFieldsDark_Search_views_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchFieldsDark_Search_views_en.png new file mode 100644 index 0000000000..c147670cee --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchFieldsDark_Search_views_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:39e0775e5c569a95653ab922084c4056635bec2056441771af3c8a3739a84901 +size 8143 diff --git a/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchFieldsLight_Search_views_en.png b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchFieldsLight_Search_views_en.png new file mode 100644 index 0000000000..21ed56ed1f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/libraries.designsystem.theme.components_SearchFieldsLight_Search_views_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a97489a6af869148d1daadb5948f26d00e888ecf0373e6ec45eb8a5ed8b12173 +size 8383 From 40f769cabdefe60b71055f7b1be71922e511741d Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 25 Nov 2025 15:40:58 +0100 Subject: [PATCH 056/113] quality(test): fix test after AsyncData.map change --- .../space/impl/leave/LeaveSpacePresenterTest.kt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt index c99d3db361..495f0b38bd 100644 --- a/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt +++ b/features/space/impl/src/test/kotlin/io/element/android/features/space/impl/leave/LeaveSpacePresenterTest.kt @@ -62,7 +62,7 @@ class LeaveSpacePresenterTest { val state = awaitItem() assertThat(state.selectableSpaceRooms.isLoading()).isTrue() assertThat(state.leaveSpaceAction).isEqualTo(AsyncAction.Uninitialized) - skipItems(3) + skipItems(2) val stateError = awaitItem() assertThat(stateError.selectableSpaceRooms.isFailure()).isTrue() // Retry @@ -84,7 +84,7 @@ class LeaveSpacePresenterTest { presenter.test { val state = awaitItem() assertThat(state.spaceName).isNull() - skipItems(3) + skipItems(2) val finalState = awaitItem() assertThat(finalState.spaceName).isEqualTo(A_SPACE_NAME) assertThat(finalState.isLastAdmin).isTrue() @@ -120,7 +120,7 @@ class LeaveSpacePresenterTest { presenter.test { val state = awaitItem() assertThat(state.spaceName).isNull() - skipItems(3) + skipItems(2) val finalState = awaitItem() // The current state is not in the sub room list assertThat(finalState.selectableSpaceRooms.dataOrNull()!!.map { it.spaceRoom.roomId }).containsExactly(A_ROOM_ID, A_ROOM_ID_3) @@ -154,7 +154,7 @@ class LeaveSpacePresenterTest { ) ) presenter.test { - skipItems(4) + skipItems(3) val state = awaitItem() assertThat(state.spaceName).isNull() assertThat(state.isLastAdmin).isFalse() @@ -218,7 +218,7 @@ class LeaveSpacePresenterTest { ) ) presenter.test { - skipItems(4) + skipItems(3) val state = awaitItem() state.eventSink(LeaveSpaceEvents.LeaveSpace) val stateLeaving = awaitItem() From 9da27215704bbae8f2bc42e27ac693d30d6c2136 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Nov 2025 15:33:49 +0100 Subject: [PATCH 057/113] Add unit test on `toAnalyticsMemberRole()` --- .../impl/roles/ChangeRolesPresenterTest.kt | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt index 472426ff85..11b9a66319 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt @@ -534,6 +534,18 @@ class ChangeRolesPresenterTest { } } + @Test + fun `test analytics mapping`()= runTest { + val presenter = createChangeRolesPresenter() + with(presenter) { + assertThat(RoomMember.Role.User.toAnalyticsMemberRole()).isEqualTo(RoomModeration.Role.User) + assertThat(RoomMember.Role.Moderator.toAnalyticsMemberRole()).isEqualTo(RoomModeration.Role.Moderator) + assertThat(RoomMember.Role.Admin.toAnalyticsMemberRole()).isEqualTo(RoomModeration.Role.Administrator) + assertThat(RoomMember.Role.Owner(isCreator = false).toAnalyticsMemberRole()).isEqualTo(RoomModeration.Role.Administrator) + assertThat(RoomMember.Role.Owner(isCreator = true).toAnalyticsMemberRole()).isEqualTo(RoomModeration.Role.Administrator) + } + } + private fun roomPowerLevelsWithRole( role: RoomMember.Role, userId: UserId = A_USER_ID, From 8c07c011a2050cd0608c461fa40241e223041b03 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Nov 2025 16:30:16 +0100 Subject: [PATCH 058/113] Creators can downgrade owners. Fixes #5632 --- .../impl/roles/ChangeRolesPresenter.kt | 20 +++++++- .../impl/roles/ChangeRolesStateProvider.kt | 8 +--- .../impl/roles/ChangeRolesView.kt | 15 +----- .../impl/roles/ChangeRolesPresenterTest.kt | 47 ++++++++++--------- 4 files changed, 46 insertions(+), 44 deletions(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt index fdb17d6e04..f7736cb77c 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt @@ -44,6 +44,8 @@ import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.emptyFlow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach @@ -77,7 +79,23 @@ class ChangeRolesPresenter( } val saveState: MutableState> = remember { mutableStateOf(AsyncAction.Uninitialized) } val usersWithRole = produceState>(initialValue = persistentListOf()) { - room.usersWithRole(role).map { members -> members.map { it.toMatrixUser() } } + // If the role is admin, we need to include the owners as well since they implicitly have admin role + val owners = if (role == RoomMember.Role.Admin) { + combine( + room.usersWithRole(RoomMember.Role.Owner(isCreator = true)), + room.usersWithRole(RoomMember.Role.Owner(isCreator = false)), + ) { creators, superAdmins -> + creators + superAdmins + } + } else { + emptyFlow() + } + combine( + owners, + room.usersWithRole(role), + ) { owners, users -> + owners + users + }.map { members -> members.map { it.toMatrixUser() } } .onEach { users -> val previous = value value = users.toImmutableList() diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesStateProvider.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesStateProvider.kt index 2594681850..654259c02a 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesStateProvider.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesStateProvider.kt @@ -50,13 +50,7 @@ class ChangeRolesStateProvider : PreviewParameterProvider { aChangeRolesStateWithSelectedUsers().copy(savingState = AsyncAction.Loading), aChangeRolesStateWithSelectedUsers().copy(savingState = AsyncAction.Success(true)), aChangeRolesStateWithSelectedUsers().copy(savingState = AsyncAction.Failure(Exception("boom"))), - aChangeRolesStateWithOwners( - role = RoomMember.Role.Admin, - // Do not include the owners in the selectedUsers (the presenter will not do it), the View will add them - selectedUsers = listOf( - aMatrixUser(id = "@carol:server.org", displayName = "Carol"), - ) - ), + aChangeRolesStateWithOwners(role = RoomMember.Role.Admin), aChangeRolesStateWithOwners(role = RoomMember.Role.Owner(isCreator = false)), aChangeRolesStateWithOwners(role = RoomMember.Role.Owner(isCreator = false)) .copy(savingState = ConfirmingModifyingOwners), diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt index bd9969dec4..bab24d3f42 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesView.kt @@ -30,7 +30,6 @@ import androidx.compose.foundation.lazy.items import androidx.compose.foundation.lazy.rememberLazyListState import androidx.compose.material3.ExperimentalMaterial3Api import androidx.compose.runtime.Composable -import androidx.compose.runtime.remember import androidx.compose.ui.Alignment import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource @@ -72,7 +71,6 @@ import io.element.android.libraries.matrix.ui.components.SelectedUsersRowList import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableList -import kotlinx.collections.immutable.toImmutableList @OptIn(ExperimentalMaterial3Api::class) @Composable @@ -222,18 +220,7 @@ private fun SearchResultsList( state = lazyListState, ) { item { - val usersInHorizontalRow = remember(searchResults.owners, selectedUsers) { - if (currentRole == RoomMember.Role.Admin) { - // Also include the owners in the horizontal list - val owners = searchResults.owners.map { - it.toMatrixUser() - } - (owners + selectedUsers).toImmutableList() - } else { - selectedUsers - } - } - selectedUsersList(usersInHorizontalRow) + selectedUsersList(selectedUsers) } if (searchResults.owners.isNotEmpty()) { stickyHeader { ListSectionHeader(text = stringResource(R.string.screen_room_roles_and_permissions_owners)) } diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt index 11b9a66319..4bc39fd971 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt @@ -106,6 +106,7 @@ class ChangeRolesPresenterTest { awaitItem().run { assertThat(canChangeMemberRole(A_USER_ID_2)).isTrue() // Admin assertThat(canChangeMemberRole(A_USER_ID_3)).isTrue() // Moderator + assertThat(canChangeMemberRole(superAdminUserId)).isTrue() // Super admin assertThat(canChangeMemberRole(creatorUserId)).isFalse() // Owner } } @@ -170,7 +171,7 @@ class ChangeRolesPresenterTest { } val presenter = createChangeRolesPresenter(room = room) presenter.test { - skipItems(1) + skipItems(2) awaitItem().searchResults.run { assertThat(this).isInstanceOf(SearchBarResultState.Results::class.java) val results = (this as SearchBarResultState.Results).results @@ -424,11 +425,14 @@ class ChangeRolesPresenterTest { analyticsService = analyticsService ) presenter.test { - skipItems(2) + skipItems(1) val initialState = awaitItem() - assertThat(initialState.selectedUsers).hasSize(1) + assertThat(initialState.selectedUsers).isEmpty() initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2))) - awaitItem().eventSink(ChangeRolesEvent.Save) + awaitItem().also { + assertThat(it.selectedUsers).hasSize(1) + it.eventSink(ChangeRolesEvent.Save) + } assertThat(awaitItem().savingState).isInstanceOf(AsyncAction.Loading::class.java) assertThat(awaitItem().savingState).isEqualTo(AsyncAction.Success(true)) assertThat(analyticsService.capturedEvents.last()).isEqualTo(RoomModeration(RoomModeration.Action.ChangeMemberRole, RoomModeration.Role.Moderator)) @@ -459,14 +463,13 @@ class ChangeRolesPresenterTest { analyticsService = analyticsService ) presenter.test { - skipItems(1) val initialState = awaitItem() - assertThat(initialState.selectedUsers).hasSize(1) - + assertThat(initialState.selectedUsers).isEmpty() initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2))) - - awaitItem().eventSink(ChangeRolesEvent.Save) - + awaitItem().also { + assertThat(it.selectedUsers).hasSize(1) + it.eventSink(ChangeRolesEvent.Save) + } assertThat(awaitItem().savingState.isConfirming()).isTrue() } } @@ -494,12 +497,12 @@ class ChangeRolesPresenterTest { presenter.test { skipItems(2) val initialState = awaitItem() - assertThat(initialState.selectedUsers).hasSize(1) - + assertThat(initialState.selectedUsers).hasSize(2) initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2))) - - awaitItem().eventSink(ChangeRolesEvent.Save) - + awaitItem().also { + assertThat(it.selectedUsers).hasSize(1) + it.eventSink(ChangeRolesEvent.Save) + } val loadingState = awaitItem() assertThat(loadingState.savingState).isInstanceOf(AsyncAction.Loading::class.java) assertThat(awaitItem().savingState).isEqualTo(AsyncAction.Success(true)) @@ -517,25 +520,25 @@ class ChangeRolesPresenterTest { } val presenter = createChangeRolesPresenter(role = RoomMember.Role.Moderator, room = room) presenter.test { - skipItems(2) + skipItems(1) val initialState = awaitItem() - assertThat(initialState.selectedUsers).hasSize(1) - + assertThat(initialState.selectedUsers).isEmpty() initialState.eventSink(ChangeRolesEvent.UserSelectionToggled(MatrixUser(A_USER_ID_2))) - - awaitItem().eventSink(ChangeRolesEvent.Save) + awaitItem().also { + assertThat(it.selectedUsers).hasSize(1) + it.eventSink(ChangeRolesEvent.Save) + } val loadingState = awaitItem() assertThat(loadingState.savingState).isInstanceOf(AsyncAction.Loading::class.java) val failedState = awaitItem() assertThat(failedState.savingState).isInstanceOf(AsyncAction.Failure::class.java) - failedState.eventSink(ChangeRolesEvent.CloseDialog) assertThat(awaitItem().savingState).isEqualTo(AsyncAction.Uninitialized) } } @Test - fun `test analytics mapping`()= runTest { + fun `test analytics mapping`() = runTest { val presenter = createChangeRolesPresenter() with(presenter) { assertThat(RoomMember.Role.User.toAnalyticsMemberRole()).isEqualTo(RoomModeration.Role.User) From 672a6fe6b03b652db18f06d822865b2970773c3a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 25 Nov 2025 17:03:00 +0100 Subject: [PATCH 059/113] hasSize(0) -> isEmpty() --- .../voicemessages/composer/VoiceMessageComposerPresenterTest.kt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/VoiceMessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/VoiceMessageComposerPresenterTest.kt index f3bc720792..73688d2db4 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/VoiceMessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/VoiceMessageComposerPresenterTest.kt @@ -408,7 +408,7 @@ class VoiceMessageComposerPresenterTest { val finalState = awaitItem() assertThat(finalState.voiceMessageState).isEqualTo(aPreviewState(isSending = true)) sendVoiceMessageResult.assertions().isNeverCalled() - assertThat(analyticsService.trackedErrors).hasSize(0) + assertThat(analyticsService.trackedErrors).isEmpty() voiceRecorder.assertCalls(started = 1, stopped = 1, deleted = 0) testPauseAndDestroy(finalState) From 5c0c5e394a6967fbff0d29ef978f8db316a1185e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 10:27:08 +0100 Subject: [PATCH 060/113] fix(deps): update dependency org.maplibre.gl:android-sdk to v12.2.0 (#5814) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 25c76cb3fb..ae78b78632 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -207,7 +207,7 @@ vanniktech_blurhash = "com.vanniktech:blurhash:0.3.0" telephoto_zoomableimage = { module = "me.saket.telephoto:zoomable-image-coil", version.ref = "telephoto" } telephoto_flick = { module = "me.saket.telephoto:flick-android", version.ref = "telephoto" } statemachine = "com.freeletics.flowredux:compose:1.2.2" -maplibre = "org.maplibre.gl:android-sdk:12.1.3" +maplibre = "org.maplibre.gl:android-sdk:12.2.0" maplibre_ktx = "org.maplibre.gl:android-sdk-ktx-v7:3.0.2" maplibre_annotation = "org.maplibre.gl:android-plugin-annotation-v9:3.0.2" opusencoder = "io.element.android:opusencoder:1.2.0" From 7159b7003a52da78c6d7b7a613b6dab57796b668 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 10:28:38 +0100 Subject: [PATCH 061/113] chore(deps): update actions/checkout action to v6 (#5805) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- .github/workflows/build.yml | 2 +- .github/workflows/build_enterprise.yml | 2 +- .github/workflows/danger.yml | 2 +- .github/workflows/gradle-wrapper-update.yml | 2 +- .github/workflows/maestro-local.yml | 4 ++-- .github/workflows/nightly.yml | 2 +- .github/workflows/nightlyReports.yml | 2 +- .github/workflows/quality.yml | 22 ++++++++++----------- .github/workflows/release.yml | 6 +++--- .github/workflows/sonar.yml | 2 +- .github/workflows/sync-localazy.yml | 2 +- .github/workflows/sync-sas-strings.yml | 2 +- 12 files changed, 25 insertions(+), 25 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 6c77cb3770..ef6b3773cd 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -25,7 +25,7 @@ jobs: group: ${{ github.ref == 'refs/heads/develop' && format('build-develop-{0}-{1}', matrix.variant, github.sha) || format('build-{0}-{1}', matrix.variant, github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 diff --git a/.github/workflows/build_enterprise.yml b/.github/workflows/build_enterprise.yml index bce9d923f3..81e17d6189 100644 --- a/.github/workflows/build_enterprise.yml +++ b/.github/workflows/build_enterprise.yml @@ -27,7 +27,7 @@ jobs: group: ${{ github.ref == 'refs/heads/develop' && format('build-develop-enterprise-{0}-{1}', matrix.variant, github.sha) || format('build-enterprise-{0}-{1}', matrix.variant, github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 diff --git a/.github/workflows/danger.yml b/.github/workflows/danger.yml index e4300b3321..f7c8fccc62 100644 --- a/.github/workflows/danger.yml +++ b/.github/workflows/danger.yml @@ -9,7 +9,7 @@ jobs: # Skip in forks, it doesn't work even with the fallback token if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Add SSH private keys for submodule repositories uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 with: diff --git a/.github/workflows/gradle-wrapper-update.yml b/.github/workflows/gradle-wrapper-update.yml index f826bb8205..3b0fac5309 100644 --- a/.github/workflows/gradle-wrapper-update.yml +++ b/.github/workflows/gradle-wrapper-update.yml @@ -11,7 +11,7 @@ jobs: # Skip in forks if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - uses: actions/setup-java@v5 name: Use JDK 21 if: (github.event_name == 'pull_request' && github.event.pull_request.fork == null) || github.event_name == 'workflow_dispatch' diff --git a/.github/workflows/maestro-local.yml b/.github/workflows/maestro-local.yml index ff0ac49f5c..460fdcf6c2 100644 --- a/.github/workflows/maestro-local.yml +++ b/.github/workflows/maestro-local.yml @@ -23,7 +23,7 @@ jobs: group: ${{ format('maestro-{0}', github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 @@ -62,7 +62,7 @@ jobs: group: ${{ format('maestro-{0}', github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 if: (github.event_name == 'pull_request' && github.event.pull_request.fork == null) || github.event_name == 'workflow_dispatch' with: # Ensure we are building the branch and not the branch after being merged on develop diff --git a/.github/workflows/nightly.yml b/.github/workflows/nightly.yml index b494d9fe8c..71a2d0a595 100644 --- a/.github/workflows/nightly.yml +++ b/.github/workflows/nightly.yml @@ -16,7 +16,7 @@ jobs: runs-on: ubuntu-latest if: ${{ github.repository == 'element-hq/element-x-android' }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Use JDK 21 uses: actions/setup-java@v5 with: diff --git a/.github/workflows/nightlyReports.yml b/.github/workflows/nightlyReports.yml index 080cf99b05..46818a1749 100644 --- a/.github/workflows/nightlyReports.yml +++ b/.github/workflows/nightlyReports.yml @@ -60,7 +60,7 @@ jobs: name: Dependency analysis runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Use JDK 21 uses: actions/setup-java@v5 with: diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 7600d8965c..cc4b9db7e1 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -17,7 +17,7 @@ jobs: name: Search for forbidden patterns runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Add SSH private keys for submodule repositories uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }} @@ -33,7 +33,7 @@ jobs: name: Search for invalid screenshot files runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Set up Python 3.12 uses: actions/setup-python@v6 with: @@ -45,7 +45,7 @@ jobs: name: Search for invalid dependencies runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Use JDK 21 uses: actions/setup-java@v5 with: @@ -71,7 +71,7 @@ jobs: group: ${{ github.ref == 'refs/heads/main' && format('check-konsist-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('check-konsist-develop-{0}', github.sha) || format('check-konsist-{0}', github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 @@ -111,7 +111,7 @@ jobs: group: ${{ github.ref == 'refs/heads/main' && format('check-compose-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('check-compose-develop-{0}', github.sha) || format('check-compose-{0}', github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 @@ -144,7 +144,7 @@ jobs: group: ${{ github.ref == 'refs/heads/main' && format('check-lint-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('check-lint-develop-{0}', github.sha) || format('check-lint-{0}', github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 @@ -188,7 +188,7 @@ jobs: group: ${{ github.ref == 'refs/heads/main' && format('check-detekt-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('check-detekt-develop-{0}', github.sha) || format('check-detekt-{0}', github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 @@ -228,7 +228,7 @@ jobs: group: ${{ github.ref == 'refs/heads/main' && format('check-ktlint-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('check-ktlint-develop-{0}', github.sha) || format('check-ktlint-{0}', github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 @@ -268,7 +268,7 @@ jobs: group: ${{ github.ref == 'refs/heads/main' && format('check-knit-main-{0}', github.sha) || github.ref == 'refs/heads/develop' && format('check-knit-develop-{0}', github.sha) || format('check-knit-{0}', github.ref) }} cancel-in-progress: true steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 @@ -299,7 +299,7 @@ jobs: name: Check shell scripts runs-on: ubuntu-latest steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Run shellcheck uses: ludeeus/action-shellcheck@2.0.0 with: @@ -311,7 +311,7 @@ jobs: needs: [konsist, lint, ktlint, detekt] if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 29ff4a5373..919897deed 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,7 +18,7 @@ jobs: group: ${{ format('build-release-main-gplay-{0}', github.sha) }} cancel-in-progress: true steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Use JDK 21 uses: actions/setup-java@v5 with: @@ -52,7 +52,7 @@ jobs: group: ${{ format('build-release-main-enterprise-{0}', github.sha) }} cancel-in-progress: true steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Add SSH private keys for submodule repositories uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }} @@ -87,7 +87,7 @@ jobs: group: ${{ format('build-release-main-fdroid-{0}', github.sha) }} cancel-in-progress: true steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Use JDK 21 uses: actions/setup-java@v5 with: diff --git a/.github/workflows/sonar.yml b/.github/workflows/sonar.yml index acfe6ba87f..c289102116 100644 --- a/.github/workflows/sonar.yml +++ b/.github/workflows/sonar.yml @@ -22,7 +22,7 @@ jobs: group: ${{ format('sonar-{0}', github.ref) }} cancel-in-progress: ${{ github.ref != 'refs/heads/main' && github.ref != 'refs/heads/develop' }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 with: # Ensure we are building the branch and not the branch after being merged on develop # https://github.com/actions/checkout/issues/881 diff --git a/.github/workflows/sync-localazy.yml b/.github/workflows/sync-localazy.yml index 404af92f30..073c075502 100644 --- a/.github/workflows/sync-localazy.yml +++ b/.github/workflows/sync-localazy.yml @@ -11,7 +11,7 @@ jobs: # Skip in forks if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }} steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Use JDK 21 uses: actions/setup-java@v5 with: diff --git a/.github/workflows/sync-sas-strings.yml b/.github/workflows/sync-sas-strings.yml index e461845c9c..ca42b8fbe6 100644 --- a/.github/workflows/sync-sas-strings.yml +++ b/.github/workflows/sync-sas-strings.yml @@ -12,7 +12,7 @@ jobs: if: ${{ github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == 'element-hq/element-x-android' }} # No concurrency required, runs every time on a schedule. steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@v6 - name: Set up Python 3.12 uses: actions/setup-python@v6 with: From 1067591d9ad847b75e248d5a6a65ab12f13689f0 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 10:52:12 +0100 Subject: [PATCH 062/113] fix(deps): update dependency com.google.testparameterinjector:test-parameter-injector to v1.20 (#5800) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index ae78b78632..585220fb8d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -165,7 +165,7 @@ test_mockk = "io.mockk:mockk:1.14.6" test_konsist = "com.lemonappdev:konsist:0.17.3" test_turbine = "app.cash.turbine:turbine:1.2.1" test_truth = "com.google.truth:truth:1.4.5" -test_parameter_injector = "com.google.testparameterinjector:test-parameter-injector:1.19" +test_parameter_injector = "com.google.testparameterinjector:test-parameter-injector:1.20" test_robolectric = "org.robolectric:robolectric:4.15.1" test_appyx_junit = { module = "com.bumble.appyx:testing-junit4", version.ref = "appyx" } test_composable_preview_scanner = "io.github.sergio-sastre.ComposablePreviewScanner:android:0.7.2" From b04524e56673710cc0ab479d9a8e8ddadec6bb77 Mon Sep 17 00:00:00 2001 From: ganfra Date: Mon, 17 Nov 2025 20:53:55 +0100 Subject: [PATCH 063/113] misc : use new_latest_event api (+ some renaming) --- .../home/impl/components/RoomSummaryRow.kt | 2 +- .../datasource/RoomListRoomSummaryFactory.kt | 10 +- .../home/impl/model/RoomListRoomSummary.kt | 2 +- .../impl/model/RoomListRoomSummaryProvider.kt | 2 +- .../RoomListRoomSummaryFactoryTest.kt | 6 +- .../impl/model/RoomListBaseRoomSummaryTest.kt | 2 +- .../impl/roomlist/RoomListPresenterTest.kt | 8 +- .../home/impl/roomlist/RoomListViewTest.kt | 6 +- .../search/RoomListSearchPresenterTest.kt | 4 +- .../components/TimelineItemEventRow.kt | 8 +- .../event/TimelineItemContentFactory.kt | 4 +- .../impl/timeline/model/TimelineItem.kt | 4 +- .../RedactedVoiceMessageManagerTest.kt | 4 +- ...rmatter.kt => RoomLatestEventFormatter.kt} | 6 +- ....kt => DefaultRoomLatestEventFormatter.kt} | 46 +++- ...efaultPinnedMessagesBannerFormatterTest.kt | 4 +- ...=> DefaultRoomLatestEventFormatterTest.kt} | 204 +++++++++--------- ...ter.kt => FakeRoomLatestEventFormatter.kt} | 8 +- .../matrix/api/room/message/RoomMessage.kt | 20 -- .../matrix/api/roomlist/LatestEventValue.kt | 31 +++ .../matrix/api/roomlist/RoomSummary.kt | 9 +- .../matrix/api/timeline/item/ThreadSummary.kt | 4 +- .../timeline/item/event/EventTimelineItem.kt | 2 +- .../api/timeline/item/event/InReplyTo.kt | 2 +- ...leTimelineDetails.kt => ProfileDetails.kt} | 22 +- .../item/event/ProfileTimelineDetailsTest.kt | 12 +- .../impl/room/message/RoomMessageFactory.kt | 28 --- .../matrix/impl/roomlist/RoomListFactory.kt | 4 +- .../impl/roomlist/RoomSummaryFactory.kt | 30 ++- .../impl/roomlist/RoomSummaryListProcessor.kt | 4 +- .../item/event/EventTimelineItemMapper.kt | 12 +- .../roomlist/RoomSummaryListProcessorTest.kt | 2 +- .../test/room/LatestEventValueFixture.kt | 48 +++++ .../matrix/test/room/RoomSummaryFixture.kt | 26 +-- .../matrix/test/timeline/TimelineFixture.kt | 8 +- .../ui/messages/reply/InReplyToDetails.kt | 4 +- .../reply/InReplyToDetailsProvider.kt | 4 +- .../matrix/ui/messages/reply/InReplyToView.kt | 4 +- .../matrix/ui/messages/sender/SenderName.kt | 14 +- .../messages/sender/SenderNameDataProvider.kt | 8 +- .../ui/messages/reply/InReplyToDetailTest.kt | 8 +- .../messages/reply/InReplyToMetadataKtTest.kt | 6 +- 42 files changed, 352 insertions(+), 290 deletions(-) rename libraries/eventformatter/api/src/main/kotlin/io/element/android/libraries/eventformatter/api/{RoomLastMessageFormatter.kt => RoomLatestEventFormatter.kt} (59%) rename libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/{DefaultRoomLastMessageFormatter.kt => DefaultRoomLatestEventFormatter.kt} (82%) rename libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/{DefaultBaseRoomLastMessageFormatterTest.kt => DefaultRoomLatestEventFormatterTest.kt} (79%) rename libraries/eventformatter/test/src/main/kotlin/io/element/android/libraries/eventformatter/test/{FakeRoomLastMessageFormatter.kt => FakeRoomLatestEventFormatter.kt} (59%) delete mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/message/RoomMessage.kt create mode 100644 libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/LatestEventValue.kt rename libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/{ProfileTimelineDetails.kt => ProfileDetails.kt} (68%) delete mode 100644 libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/message/RoomMessageFactory.kt create mode 100644 libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/LatestEventValueFixture.kt diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt index a9a1745b85..c43f7dcdd2 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt @@ -277,7 +277,7 @@ private fun MessagePreviewAndIndicatorRow( val messagePreview = if (room.isTombstoned) { stringResource(R.string.screen_roomlist_tombstoned_room_description) } else { - room.lastMessage.orEmpty() + room.latestEvent.orEmpty() } val annotatedMessagePreview = messagePreview as? AnnotatedString ?: AnnotatedString(text = messagePreview.toString()) Text( diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt index 62b34ba8de..935410e572 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt @@ -15,7 +15,7 @@ import io.element.android.libraries.core.extensions.orEmpty import io.element.android.libraries.dateformatter.api.DateFormatter import io.element.android.libraries.dateformatter.api.DateFormatterMode import io.element.android.libraries.designsystem.components.avatar.AvatarSize -import io.element.android.libraries.eventformatter.api.RoomLastMessageFormatter +import io.element.android.libraries.eventformatter.api.RoomLatestEventFormatter import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.isDm import io.element.android.libraries.matrix.api.roomlist.RoomSummary @@ -26,7 +26,7 @@ import kotlinx.collections.immutable.toImmutableList @Inject class RoomListRoomSummaryFactory( private val dateFormatter: DateFormatter, - private val roomLastMessageFormatter: RoomLastMessageFormatter, + private val roomLatestEventFormatter: RoomLatestEventFormatter, ) { fun create(roomSummary: RoomSummary): RoomListRoomSummary { val roomInfo = roomSummary.info @@ -40,13 +40,11 @@ class RoomListRoomSummaryFactory( numberOfUnreadNotifications = roomInfo.numUnreadNotifications, isMarkedUnread = roomInfo.isMarkedUnread, timestamp = dateFormatter.format( - timestamp = roomSummary.lastMessageTimestamp, + timestamp = roomSummary.latestEventTimestamp, mode = DateFormatterMode.TimeOrDate, useRelative = true, ), - lastMessage = roomSummary.lastMessage?.let { message -> - roomLastMessageFormatter.format(message.event, roomInfo.isDm) - }.orEmpty(), + latestEvent = roomLatestEventFormatter.format(roomSummary.latestEvent, roomInfo.isDm).orEmpty(), avatarData = avatarData, userDefinedNotificationMode = roomInfo.userDefinedNotificationMode, hasRoomCall = roomInfo.hasRoomCall, diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummary.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummary.kt index 215ded2081..aa983baf56 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummary.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummary.kt @@ -29,7 +29,7 @@ data class RoomListRoomSummary( val numberOfUnreadNotifications: Long, val isMarkedUnread: Boolean, val timestamp: String?, - val lastMessage: CharSequence?, + val latestEvent: CharSequence?, val avatarData: AvatarData, val userDefinedNotificationMode: RoomNotificationMode?, val hasRoomCall: Boolean, diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt index e00d7564ba..e88d6d0972 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt @@ -171,7 +171,7 @@ internal fun aRoomListRoomSummary( numberOfUnreadNotifications = numberOfUnreadNotifications, isMarkedUnread = isMarkedUnread, timestamp = timestamp, - lastMessage = lastMessage, + latestEvent = lastMessage, avatarData = avatarData, userDefinedNotificationMode = notificationMode, hasRoomCall = hasRoomCall, diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactoryTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactoryTest.kt index fd51c3b53e..941f889f69 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactoryTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactoryTest.kt @@ -10,12 +10,12 @@ package io.element.android.features.home.impl.datasource import io.element.android.libraries.dateformatter.api.DateFormatter import io.element.android.libraries.dateformatter.test.FakeDateFormatter -import io.element.android.libraries.eventformatter.api.RoomLastMessageFormatter +import io.element.android.libraries.eventformatter.api.RoomLatestEventFormatter fun aRoomListRoomSummaryFactory( dateFormatter: DateFormatter = FakeDateFormatter { _, _, _ -> "Today" }, - roomLastMessageFormatter: RoomLastMessageFormatter = RoomLastMessageFormatter { _, _ -> "Hey" } + roomLatestEventFormatter: RoomLatestEventFormatter = RoomLatestEventFormatter { _, _ -> "Hey" } ) = RoomListRoomSummaryFactory( dateFormatter = dateFormatter, - roomLastMessageFormatter = roomLastMessageFormatter + roomLatestEventFormatter = roomLatestEventFormatter ) diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt index 72465e15fd..cbf6c145ad 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt @@ -96,7 +96,7 @@ internal fun createRoomListRoomSummary( numberOfUnreadNotifications = numberOfUnreadNotifications, isMarkedUnread = isMarkedUnread, timestamp = timestamp, - lastMessage = "", + latestEvent = "", avatarData = AvatarData(id = A_ROOM_ID.value, name = A_ROOM_NAME, size = AvatarSize.RoomListItem), displayType = displayType, userDefinedNotificationMode = userDefinedNotificationMode, diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt index cf535e187d..cf636e26ca 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt @@ -35,8 +35,8 @@ import io.element.android.features.rageshake.test.logs.FakeAnnouncementService import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.dateformatter.api.DateFormatter import io.element.android.libraries.dateformatter.test.FakeDateFormatter -import io.element.android.libraries.eventformatter.api.RoomLastMessageFormatter -import io.element.android.libraries.eventformatter.test.FakeRoomLastMessageFormatter +import io.element.android.libraries.eventformatter.api.RoomLatestEventFormatter +import io.element.android.libraries.eventformatter.test.FakeRoomLatestEventFormatter import io.element.android.libraries.fullscreenintent.api.aFullScreenIntentPermissionsState import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId @@ -638,7 +638,7 @@ class RoomListPresenterTest { client: MatrixClient = FakeMatrixClient(), leaveRoomState: LeaveRoomState = aLeaveRoomState(), dateFormatter: DateFormatter = FakeDateFormatter(), - roomLastMessageFormatter: RoomLastMessageFormatter = FakeRoomLastMessageFormatter(), + roomLatestEventFormatter: RoomLatestEventFormatter = FakeRoomLatestEventFormatter(), sessionPreferencesStore: SessionPreferencesStore = InMemorySessionPreferencesStore(), analyticsService: AnalyticsService = FakeAnalyticsService(), filtersPresenter: Presenter = Presenter { aRoomListFiltersState() }, @@ -655,7 +655,7 @@ class RoomListPresenterTest { roomListService = client.roomListService, roomListRoomSummaryFactory = aRoomListRoomSummaryFactory( dateFormatter = dateFormatter, - roomLastMessageFormatter = roomLastMessageFormatter, + roomLatestEventFormatter = roomLatestEventFormatter, ), coroutineDispatchers = testCoroutineDispatchers(), notificationSettingsService = client.notificationSettingsService, diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt index 5c3bef26c4..7855180926 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt @@ -170,7 +170,7 @@ class RoomListViewTest { // Remove automatic initial events eventsRecorder.clear() - rule.onNodeWithText(room0.lastMessage!!.toString()).performClick() + rule.onNodeWithText(room0.latestEvent!!.toString()).performClick() } eventsRecorder.assertEmpty() @@ -192,7 +192,7 @@ class RoomListViewTest { ) // Remove automatic initial events eventsRecorder.clear() - rule.onNodeWithText(room0.lastMessage!!.toString()) + rule.onNodeWithText(room0.latestEvent!!.toString()) .performClick() .performClick() } @@ -214,7 +214,7 @@ class RoomListViewTest { // Remove automatic initial events eventsRecorder.clear() - rule.onNodeWithText(room0.lastMessage!!.toString()).performTouchInput { longClick() } + rule.onNodeWithText(room0.latestEvent!!.toString()).performTouchInput { longClick() } eventsRecorder.assertSingle(RoomListEvents.ShowContextMenu(room0)) } diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/search/RoomListSearchPresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/search/RoomListSearchPresenterTest.kt index d21f3a09a8..dee0601915 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/search/RoomListSearchPresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/search/RoomListSearchPresenterTest.kt @@ -14,7 +14,7 @@ import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import io.element.android.features.home.impl.datasource.aRoomListRoomSummaryFactory import io.element.android.libraries.dateformatter.test.FakeDateFormatter -import io.element.android.libraries.eventformatter.test.FakeRoomLastMessageFormatter +import io.element.android.libraries.eventformatter.test.FakeRoomLatestEventFormatter import io.element.android.libraries.matrix.api.roomlist.RoomListFilter import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.test.room.aRoomSummary @@ -126,7 +126,7 @@ fun TestScope.createRoomListSearchPresenter( roomListService = roomListService, roomSummaryFactory = aRoomListRoomSummaryFactory( dateFormatter = FakeDateFormatter(), - roomLastMessageFormatter = FakeRoomLastMessageFormatter(), + roomLatestEventFormatter = FakeRoomLatestEventFormatter(), ), coroutineDispatchers = testCoroutineDispatchers(), ), diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt index 2e2ea2b3e8..1f40e94a9b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/components/TimelineItemEventRow.kt @@ -103,7 +103,7 @@ import io.element.android.libraries.matrix.api.timeline.item.EmbeddedEventInfo import io.element.android.libraries.matrix.api.timeline.item.ThreadSummary import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent -import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType import io.element.android.libraries.matrix.api.timeline.item.event.getAvatarUrl import io.element.android.libraries.matrix.api.timeline.item.event.getDisambiguatedDisplayName @@ -542,7 +542,7 @@ private fun TimelineItemEventRowContent( @Composable private fun MessageSenderInformation( senderId: UserId, - senderProfile: ProfileTimelineDetails, + senderProfile: ProfileDetails, senderAvatar: AvatarData, onClick: () -> Unit, modifier: Modifier = Modifier @@ -844,7 +844,7 @@ internal fun TimelineItemEventRowWithThreadSummaryPreview() = ElementPreview { type = TextMessageType("This is the latest message in the thread", null) ), senderId = UserId("@user:id"), - senderProfile = ProfileTimelineDetails.Ready( + senderProfile = ProfileDetails.Ready( displayName = "Alice", avatarUrl = null, displayNameAmbiguous = false, @@ -877,7 +877,7 @@ internal fun ThreadSummaryViewPreview() { type = TextMessageType(body, null) ), senderId = UserId("@user:id"), - senderProfile = ProfileTimelineDetails.Ready( + senderProfile = ProfileDetails.Ready( displayName = "Alice", avatarUrl = null, displayNameAmbiguous = true, diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentFactory.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentFactory.kt index ef69c0d6a1..31cf689ef8 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentFactory.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/factories/event/TimelineItemContentFactory.kt @@ -25,7 +25,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.LegacyCallInv import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent import io.element.android.libraries.matrix.api.timeline.item.event.PollContent import io.element.android.libraries.matrix.api.timeline.item.event.ProfileChangeContent -import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails import io.element.android.libraries.matrix.api.timeline.item.event.RedactedContent import io.element.android.libraries.matrix.api.timeline.item.event.RoomMembershipContent import io.element.android.libraries.matrix.api.timeline.item.event.StateContent @@ -63,7 +63,7 @@ class TimelineItemContentFactory( eventId: EventId?, isEditable: Boolean, sender: UserId, - senderProfile: ProfileTimelineDetails, + senderProfile: ProfileDetails, ): TimelineItemEventContent { val isOutgoing = sessionId == sender return when (itemContent) { diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt index 590090b6ed..1f01b16012 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/model/TimelineItem.kt @@ -28,7 +28,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransa import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield import io.element.android.libraries.matrix.api.timeline.item.event.MessageShieldProvider -import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails import io.element.android.libraries.matrix.api.timeline.item.event.SendHandleProvider import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemDebugInfoProvider import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin @@ -69,7 +69,7 @@ sealed interface TimelineItem { val eventId: EventId? = null, val transactionId: TransactionId? = null, val senderId: UserId, - val senderProfile: ProfileTimelineDetails, + val senderProfile: ProfileDetails, val senderAvatar: AvatarData, val content: TimelineItemEventContent, val sentTimeMillis: Long = 0L, diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/RedactedVoiceMessageManagerTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/RedactedVoiceMessageManagerTest.kt index e69e83ad04..8bced93023 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/RedactedVoiceMessageManagerTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/timeline/RedactedVoiceMessageManagerTest.kt @@ -15,7 +15,7 @@ import io.element.android.libraries.matrix.api.core.UniqueId import io.element.android.libraries.matrix.api.timeline.MatrixTimelineItem import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem -import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails import io.element.android.libraries.matrix.api.timeline.item.event.RedactedContent import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.AN_EVENT_ID_2 @@ -86,7 +86,7 @@ fun aRedactedMatrixTimeline(eventId: EventId) = listOf( reactions = persistentListOf(), receipts = persistentListOf(), sender = A_USER_ID, - senderProfile = ProfileTimelineDetails.Unavailable, + senderProfile = ProfileDetails.Unavailable, timestamp = 9442, content = RedactedContent, origin = null, diff --git a/libraries/eventformatter/api/src/main/kotlin/io/element/android/libraries/eventformatter/api/RoomLastMessageFormatter.kt b/libraries/eventformatter/api/src/main/kotlin/io/element/android/libraries/eventformatter/api/RoomLatestEventFormatter.kt similarity index 59% rename from libraries/eventformatter/api/src/main/kotlin/io/element/android/libraries/eventformatter/api/RoomLastMessageFormatter.kt rename to libraries/eventformatter/api/src/main/kotlin/io/element/android/libraries/eventformatter/api/RoomLatestEventFormatter.kt index dfdf15cc24..5eb7713b54 100644 --- a/libraries/eventformatter/api/src/main/kotlin/io/element/android/libraries/eventformatter/api/RoomLastMessageFormatter.kt +++ b/libraries/eventformatter/api/src/main/kotlin/io/element/android/libraries/eventformatter/api/RoomLatestEventFormatter.kt @@ -8,8 +8,8 @@ package io.element.android.libraries.eventformatter.api -import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem +import io.element.android.libraries.matrix.api.roomlist.LatestEventValue -fun interface RoomLastMessageFormatter { - fun format(event: EventTimelineItem, isDmRoom: Boolean): CharSequence? +fun interface RoomLatestEventFormatter { + fun format(latestEvent: LatestEventValue, isDmRoom: Boolean): CharSequence? } diff --git a/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatter.kt b/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatter.kt similarity index 82% rename from libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatter.kt rename to libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatter.kt index 4373977ec8..48b8c83bc6 100644 --- a/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLastMessageFormatter.kt +++ b/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatter.kt @@ -10,13 +10,15 @@ package io.element.android.libraries.eventformatter.impl import dev.zacsweers.metro.ContributesBinding import io.element.android.libraries.di.SessionScope -import io.element.android.libraries.eventformatter.api.RoomLastMessageFormatter +import io.element.android.libraries.eventformatter.api.RoomLatestEventFormatter import io.element.android.libraries.eventformatter.impl.mode.RenderingMode +import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.permalink.PermalinkParser +import io.element.android.libraries.matrix.api.roomlist.LatestEventValue import io.element.android.libraries.matrix.api.timeline.item.event.AudioMessageType import io.element.android.libraries.matrix.api.timeline.item.event.CallNotifyContent import io.element.android.libraries.matrix.api.timeline.item.event.EmoteMessageType -import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem +import io.element.android.libraries.matrix.api.timeline.item.event.EventContent import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseMessageLikeContent import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseStateContent import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType @@ -45,22 +47,46 @@ import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.services.toolbox.api.strings.StringProvider @ContributesBinding(SessionScope::class) -class DefaultRoomLastMessageFormatter( +class DefaultRoomLatestEventFormatter( private val sp: StringProvider, private val roomMembershipContentFormatter: RoomMembershipContentFormatter, private val profileChangeContentFormatter: ProfileChangeContentFormatter, private val stateContentFormatter: StateContentFormatter, - private val permalinkParser: PermalinkParser -) : RoomLastMessageFormatter { + private val permalinkParser: PermalinkParser, +) : RoomLatestEventFormatter { companion object { // Max characters to display in the last message. This works around https://github.com/element-hq/element-x-android/issues/2105 private const val MAX_SAFE_LENGTH = 500 } - override fun format(event: EventTimelineItem, isDmRoom: Boolean): CharSequence? { - val isOutgoing = event.isOwn - val senderDisambiguatedDisplayName = event.senderProfile.getDisambiguatedDisplayName(event.sender) - return when (val content = event.content) { + override fun format(latestEvent: LatestEventValue, isDmRoom: Boolean): CharSequence? { + return when (latestEvent) { + LatestEventValue.None -> null + is LatestEventValue.Local -> formatContent( + content = latestEvent.content, + isDmRoom = isDmRoom, + isOutgoing = true, + senderId = latestEvent.senderId, + senderDisambiguatedDisplayName = latestEvent.senderProfile.getDisambiguatedDisplayName(latestEvent.senderId) + ) + is LatestEventValue.Remote -> formatContent( + content = latestEvent.content, + isDmRoom = isDmRoom, + isOutgoing = latestEvent.isOwn, + senderId = latestEvent.senderId, + senderDisambiguatedDisplayName = latestEvent.senderProfile.getDisambiguatedDisplayName(latestEvent.senderId) + ) + } + } + + private fun formatContent( + content: EventContent, + isDmRoom: Boolean, + isOutgoing: Boolean, + senderId: UserId, + senderDisambiguatedDisplayName: String + ): CharSequence? { + return when (content) { is MessageContent -> content.process(senderDisambiguatedDisplayName, isDmRoom, isOutgoing) RedactedContent -> { val message = sp.getString(CommonStrings.common_message_removed) @@ -78,7 +104,7 @@ class DefaultRoomLastMessageFormatter( roomMembershipContentFormatter.format(content, senderDisambiguatedDisplayName, isOutgoing) } is ProfileChangeContent -> { - profileChangeContentFormatter.format(content, event.sender, senderDisambiguatedDisplayName, isOutgoing) + profileChangeContentFormatter.format(content, senderId, senderDisambiguatedDisplayName, isOutgoing) } is StateContent -> { stateContentFormatter.format(content, senderDisambiguatedDisplayName, isOutgoing, RenderingMode.RoomList) diff --git a/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultPinnedMessagesBannerFormatterTest.kt b/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultPinnedMessagesBannerFormatterTest.kt index c067113b2d..10c09ad41d 100644 --- a/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultPinnedMessagesBannerFormatterTest.kt +++ b/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultPinnedMessagesBannerFormatterTest.kt @@ -44,7 +44,7 @@ import io.element.android.libraries.matrix.test.media.aMediaSource import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser import io.element.android.libraries.matrix.test.timeline.aPollContent import io.element.android.libraries.matrix.test.timeline.aProfileChangeMessageContent -import io.element.android.libraries.matrix.test.timeline.aProfileTimelineDetails +import io.element.android.libraries.matrix.test.timeline.aProfileDetails import io.element.android.libraries.matrix.test.timeline.aStickerContent import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem import io.element.android.libraries.matrix.test.timeline.item.event.aRoomMembershipContent @@ -778,7 +778,7 @@ class DefaultPinnedMessagesBannerFormatterTest { content: EventContent, ): EventTimelineItem { val sender = if (sentByYou) A_USER_ID else someoneElseId - val profile = aProfileTimelineDetails(senderDisplayName) + val profile = aProfileDetails(senderDisplayName) return anEventTimelineItem( content = content, senderProfile = profile, diff --git a/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultBaseRoomLastMessageFormatterTest.kt b/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatterTest.kt similarity index 79% rename from libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultBaseRoomLastMessageFormatterTest.kt rename to libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatterTest.kt index 5b8c2c86df..96d341f447 100644 --- a/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultBaseRoomLastMessageFormatterTest.kt +++ b/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatterTest.kt @@ -15,10 +15,10 @@ import com.google.common.truth.Truth.assertWithMessage import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.media.ImageInfo import io.element.android.libraries.matrix.api.media.MediaSource +import io.element.android.libraries.matrix.api.roomlist.LatestEventValue import io.element.android.libraries.matrix.api.timeline.item.event.AudioMessageType import io.element.android.libraries.matrix.api.timeline.item.event.EmoteMessageType import io.element.android.libraries.matrix.api.timeline.item.event.EventContent -import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseMessageLikeContent import io.element.android.libraries.matrix.api.timeline.item.event.FailedToParseStateContent import io.element.android.libraries.matrix.api.timeline.item.event.FileMessageType @@ -43,11 +43,11 @@ import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.media.aMediaSource import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser +import io.element.android.libraries.matrix.test.room.aRemoteLatestEvent import io.element.android.libraries.matrix.test.timeline.aPollContent import io.element.android.libraries.matrix.test.timeline.aProfileChangeMessageContent -import io.element.android.libraries.matrix.test.timeline.aProfileTimelineDetails +import io.element.android.libraries.matrix.test.timeline.aProfileDetails import io.element.android.libraries.matrix.test.timeline.aStickerContent -import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem import io.element.android.libraries.matrix.test.timeline.item.event.aRoomMembershipContent import io.element.android.services.toolbox.impl.strings.AndroidStringProvider import org.junit.Before @@ -59,17 +59,17 @@ import org.robolectric.annotation.Config @Suppress("LargeClass") @RunWith(RobolectricTestRunner::class) -class DefaultBaseRoomLastMessageFormatterTest { +class DefaultRoomLatestEventFormatterTest { private lateinit var context: Context private lateinit var fakeMatrixClient: FakeMatrixClient - private lateinit var formatter: DefaultRoomLastMessageFormatter + private lateinit var formatter: DefaultRoomLatestEventFormatter @Before fun setup() { context = RuntimeEnvironment.getApplication() as Context fakeMatrixClient = FakeMatrixClient() val stringProvider = AndroidStringProvider(context.resources) - formatter = DefaultRoomLastMessageFormatter( + formatter = DefaultRoomLatestEventFormatter( sp = AndroidStringProvider(context.resources), roomMembershipContentFormatter = RoomMembershipContentFormatter(fakeMatrixClient, stringProvider), profileChangeContentFormatter = ProfileChangeContentFormatter(stringProvider), @@ -84,7 +84,7 @@ class DefaultBaseRoomLastMessageFormatterTest { val expected = "Message removed" val senderName = "Someone" sequenceOf(false, true).forEach { isDm -> - val message = createRoomEvent(false, senderName, RedactedContent) + val message = createLatestEvent(false, senderName, RedactedContent) val result = formatter.format(message, isDm) if (isDm) { assertThat(result).isEqualTo(expected) @@ -100,7 +100,7 @@ class DefaultBaseRoomLastMessageFormatterTest { fun `Sticker content`() { val body = "a sticker body" val info = ImageInfo(null, null, null, null, null, null, null) - val message = createRoomEvent(false, null, aStickerContent(body, info, aMediaSource(url = "url"))) + val message = createLatestEvent(false, null, aStickerContent(body, info, aMediaSource(url = "url"))) val result = formatter.format(message, false) val expectedBody = someoneElseId.value + ": Sticker (a sticker body)" assertThat(result.toString()).isEqualTo(expectedBody) @@ -112,7 +112,7 @@ class DefaultBaseRoomLastMessageFormatterTest { val expected = "Waiting for this message" val senderName = "Someone" sequenceOf(false, true).forEach { isDm -> - val message = createRoomEvent(false, senderName, UnableToDecryptContent(UnableToDecryptContent.Data.Unknown)) + val message = createLatestEvent(false, senderName, UnableToDecryptContent(UnableToDecryptContent.Data.Unknown)) val result = formatter.format(message, isDm) if (isDm) { assertThat(result).isEqualTo(expected) @@ -134,7 +134,7 @@ class DefaultBaseRoomLastMessageFormatterTest { FailedToParseStateContent("", "", ""), UnknownContent, ).forEach { type -> - val message = createRoomEvent(false, senderName, type) + val message = createLatestEvent(false, senderName, type) val result = formatter.format(message, isDm) if (isDm) { assertWithMessage("$type was not properly handled").that(result).isEqualTo(expected) @@ -198,7 +198,7 @@ class DefaultBaseRoomLastMessageFormatterTest { sequenceOf(false, true).forEach { isDm -> sharedContentMessagesTypes.forEach { type -> val content = createMessageContent(type) - val message = createRoomEvent(sentByYou = sentByYou, senderDisplayName = senderName, content = content) + val message = createLatestEvent(sentByYou = sentByYou, senderDisplayName = senderName, content = content) val result = formatter.format(message, isDmRoom = isDm) if (isDm) { resultsInDm.add(type to result) @@ -294,11 +294,11 @@ class DefaultBaseRoomLastMessageFormatterTest { val youContent = aRoomMembershipContent(A_USER_ID, null, MembershipChange.JOINED) val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), otherName, MembershipChange.JOINED) - val youJoinedRoomEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) + val youJoinedRoomEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youJoinedRoom = formatter.format(youJoinedRoomEvent, false) assertThat(youJoinedRoom).isEqualTo("You joined the room") - val someoneJoinedRoomEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneJoinedRoomEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneJoinedRoom = formatter.format(someoneJoinedRoomEvent, false) assertThat(someoneJoinedRoom).isEqualTo("$otherName joined the room") } @@ -310,11 +310,11 @@ class DefaultBaseRoomLastMessageFormatterTest { val youContent = aRoomMembershipContent(A_USER_ID, null, MembershipChange.LEFT) val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), otherName, MembershipChange.LEFT) - val youLeftRoomEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) + val youLeftRoomEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youLeftRoom = formatter.format(youLeftRoomEvent, false) assertThat(youLeftRoom).isEqualTo("You left the room") - val someoneLeftRoomEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneLeftRoomEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneLeftRoom = formatter.format(someoneLeftRoomEvent, false) assertThat(someoneLeftRoom).isEqualTo("$otherName left the room") } @@ -329,19 +329,19 @@ class DefaultBaseRoomLastMessageFormatterTest { val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.BANNED) val someoneKickedContent = aRoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.KICKED_AND_BANNED) - val youBannedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) + val youBannedEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youBanned = formatter.format(youBannedEvent, false) assertThat(youBanned).isEqualTo("You banned $third") - val youKickBannedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youKickedContent) + val youKickBannedEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = youKickedContent) val youKickedBanned = formatter.format(youKickBannedEvent, false) assertThat(youKickedBanned).isEqualTo("You banned $third") - val someoneBannedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneBannedEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneBanned = formatter.format(someoneBannedEvent, false) assertThat(someoneBanned).isEqualTo("$otherName banned $third") - val someoneKickBannedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneKickedContent) + val someoneKickBannedEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneKickedContent) val someoneKickBanned = formatter.format(someoneKickBannedEvent, false) assertThat(someoneKickBanned).isEqualTo("$otherName banned $third") } @@ -356,19 +356,19 @@ class DefaultBaseRoomLastMessageFormatterTest { val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.BANNED, A_REASON) val someoneKickedContent = aRoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.KICKED_AND_BANNED, A_REASON) - val youBannedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) + val youBannedEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youBanned = formatter.format(youBannedEvent, false) assertThat(youBanned).isEqualTo("You banned $third: $A_REASON") - val youKickBannedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youKickedContent) + val youKickBannedEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = youKickedContent) val youKickedBanned = formatter.format(youKickBannedEvent, false) assertThat(youKickedBanned).isEqualTo("You banned $third: $A_REASON") - val someoneBannedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneBannedEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneBanned = formatter.format(someoneBannedEvent, false) assertThat(someoneBanned).isEqualTo("$otherName banned $third: $A_REASON") - val someoneKickBannedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneKickedContent) + val someoneKickBannedEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneKickedContent) val someoneKickBanned = formatter.format(someoneKickBannedEvent, false) assertThat(someoneKickBanned).isEqualTo("$otherName banned $third: $A_REASON") } @@ -381,11 +381,11 @@ class DefaultBaseRoomLastMessageFormatterTest { val youContent = aRoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.UNBANNED) val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.UNBANNED) - val youUnbannedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) + val youUnbannedEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youUnbanned = formatter.format(youUnbannedEvent, false) assertThat(youUnbanned).isEqualTo("You unbanned $third") - val someoneUnbannedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneUnbannedEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneUnbanned = formatter.format(someoneUnbannedEvent, false) assertThat(someoneUnbanned).isEqualTo("$otherName unbanned $third") } @@ -398,11 +398,11 @@ class DefaultBaseRoomLastMessageFormatterTest { val youContent = aRoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.KICKED) val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.KICKED) - val youKickedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) + val youKickedEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youKicked = formatter.format(youKickedEvent, false) assertThat(youKicked).isEqualTo("You removed $third") - val someoneKickedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneKickedEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneKicked = formatter.format(someoneKickedEvent, false) assertThat(someoneKicked).isEqualTo("$otherName removed $third") } @@ -415,11 +415,11 @@ class DefaultBaseRoomLastMessageFormatterTest { val youContent = aRoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.KICKED, A_REASON) val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.KICKED, A_REASON) - val youKickedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) + val youKickedEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youKicked = formatter.format(youKickedEvent, false) assertThat(youKicked).isEqualTo("You removed $third: $A_REASON") - val someoneKickedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneKickedEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneKicked = formatter.format(someoneKickedEvent, false) assertThat(someoneKicked).isEqualTo("$otherName removed $third: $A_REASON") } @@ -432,15 +432,15 @@ class DefaultBaseRoomLastMessageFormatterTest { val youContent = aRoomMembershipContent(A_USER_ID, null, MembershipChange.INVITED) val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.INVITED) - val youWereInvitedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = youContent) + val youWereInvitedEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = youContent) val youWereInvited = formatter.format(youWereInvitedEvent, false) assertThat(youWereInvited).isEqualTo("$otherName invited you") - val youInvitedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent) + val youInvitedEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = someoneContent) val youInvited = formatter.format(youInvitedEvent, false) assertThat(youInvited).isEqualTo("You invited $third") - val someoneInvitedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneInvitedEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneInvited = formatter.format(someoneInvitedEvent, false) assertThat(someoneInvited).isEqualTo("$otherName invited $third") } @@ -452,11 +452,11 @@ class DefaultBaseRoomLastMessageFormatterTest { val youContent = aRoomMembershipContent(A_USER_ID, null, MembershipChange.INVITATION_ACCEPTED) val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), otherName, MembershipChange.INVITATION_ACCEPTED) - val youAcceptedInviteEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) + val youAcceptedInviteEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youAcceptedInvite = formatter.format(youAcceptedInviteEvent, false) assertThat(youAcceptedInvite).isEqualTo("You accepted the invite") - val someoneAcceptedInviteEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneAcceptedInviteEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneAcceptedInvite = formatter.format(someoneAcceptedInviteEvent, false) assertThat(someoneAcceptedInvite).isEqualTo("$otherName accepted the invite") } @@ -468,11 +468,11 @@ class DefaultBaseRoomLastMessageFormatterTest { val youContent = aRoomMembershipContent(A_USER_ID, null, MembershipChange.INVITATION_REJECTED) val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), otherName, MembershipChange.INVITATION_REJECTED) - val youRejectedInviteEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) + val youRejectedInviteEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youRejectedInvite = formatter.format(youRejectedInviteEvent, false) assertThat(youRejectedInvite).isEqualTo("You rejected the invitation") - val someoneRejectedInviteEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneRejectedInviteEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneRejectedInvite = formatter.format(someoneRejectedInviteEvent, false) assertThat(someoneRejectedInvite).isEqualTo("$otherName rejected the invitation") } @@ -484,11 +484,11 @@ class DefaultBaseRoomLastMessageFormatterTest { val third = "Someone" val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.INVITATION_REVOKED) - val youRevokedInviteEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent) + val youRevokedInviteEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = someoneContent) val youRevokedInvite = formatter.format(youRevokedInviteEvent, false) assertThat(youRevokedInvite).isEqualTo("You revoked the invitation for $third to join the room") - val someoneRevokedInviteEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneRevokedInviteEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneRevokedInvite = formatter.format(someoneRevokedInviteEvent, false) assertThat(someoneRevokedInvite).isEqualTo("$otherName revoked the invitation for $third to join the room") } @@ -500,11 +500,11 @@ class DefaultBaseRoomLastMessageFormatterTest { val youContent = aRoomMembershipContent(A_USER_ID, null, MembershipChange.KNOCKED) val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), otherName, MembershipChange.KNOCKED) - val youKnockedEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) + val youKnockedEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youKnocked = formatter.format(youKnockedEvent, false) assertThat(youKnocked).isEqualTo("You requested to join") - val someoneKnockedEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneKnockedEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneKnocked = formatter.format(someoneKnockedEvent, false) assertThat(someoneKnocked).isEqualTo("$otherName is requesting to join") } @@ -516,11 +516,11 @@ class DefaultBaseRoomLastMessageFormatterTest { val third = "Someone" val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.KNOCK_ACCEPTED) - val youAcceptedKnockEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent) + val youAcceptedKnockEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = someoneContent) val youAcceptedKnock = formatter.format(youAcceptedKnockEvent, false) assertThat(youAcceptedKnock).isEqualTo("You allowed $third to join") - val someoneAcceptedKnockEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneAcceptedKnockEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneAcceptedKnock = formatter.format(someoneAcceptedKnockEvent, false) assertThat(someoneAcceptedKnock).isEqualTo("$otherName granted access to $third") } @@ -532,11 +532,11 @@ class DefaultBaseRoomLastMessageFormatterTest { val youContent = aRoomMembershipContent(A_USER_ID, null, MembershipChange.KNOCK_RETRACTED) val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), null, MembershipChange.KNOCK_RETRACTED) - val youRetractedKnockEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) + val youRetractedKnockEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youRetractedKnock = formatter.format(youRetractedKnockEvent, false) assertThat(youRetractedKnock).isEqualTo("You cancelled your request to join") - val someoneRetractedKnockEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneRetractedKnockEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneRetractedKnock = formatter.format(someoneRetractedKnockEvent, false) assertThat(someoneRetractedKnock).isEqualTo("$otherName is no longer interested in joining") } @@ -549,15 +549,15 @@ class DefaultBaseRoomLastMessageFormatterTest { val youContent = aRoomMembershipContent(A_USER_ID, third, MembershipChange.KNOCK_DENIED) val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), third, MembershipChange.KNOCK_DENIED) - val youDeniedKnockEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = someoneContent) + val youDeniedKnockEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = someoneContent) val youDeniedKnock = formatter.format(youDeniedKnockEvent, false) assertThat(youDeniedKnock).isEqualTo("You rejected $third's request to join") - val someoneDeniedKnockEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneDeniedKnockEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneDeniedKnock = formatter.format(someoneDeniedKnockEvent, false) assertThat(someoneDeniedKnock).isEqualTo("$otherName rejected $third's request to join") - val someoneDeniedYourKnockEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = youContent) + val someoneDeniedYourKnockEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = youContent) val someoneDeniedYourKnock = formatter.format(someoneDeniedYourKnockEvent, false) assertThat(someoneDeniedYourKnock).isEqualTo("$otherName rejected your request to join") } @@ -569,11 +569,11 @@ class DefaultBaseRoomLastMessageFormatterTest { val youContent = aRoomMembershipContent(A_USER_ID, null, MembershipChange.NONE) val someoneContent = aRoomMembershipContent(UserId("@someone_else:domain"), otherName, MembershipChange.NONE) - val youNoneRoomEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = youContent) + val youNoneRoomEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = youContent) val youNoneRoom = formatter.format(youNoneRoomEvent, false) assertThat(youNoneRoom).isEqualTo("You made no changes") - val someoneNoneRoomEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) + val someoneNoneRoomEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = someoneContent) val someoneNoneRoom = formatter.format(someoneNoneRoomEvent, false) assertThat(someoneNoneRoom).isEqualTo("$otherName made no changes") } @@ -585,7 +585,7 @@ class DefaultBaseRoomLastMessageFormatterTest { val results = otherChanges.map { change -> val content = aRoomMembershipContent(A_USER_ID, null, change) - val event = createRoomEvent(sentByYou = false, senderDisplayName = "Someone", content = content) + val event = createLatestEvent(sentByYou = false, senderDisplayName = "Someone", content = content) val result = formatter.format(event, false) change to result } @@ -604,19 +604,19 @@ class DefaultBaseRoomLastMessageFormatterTest { val changedContent = StateContent("", OtherState.RoomAvatar("new_avatar")) val removedContent = StateContent("", OtherState.RoomAvatar(null)) - val youChangedRoomAvatarEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = changedContent) + val youChangedRoomAvatarEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = changedContent) val youChangedRoomAvatar = formatter.format(youChangedRoomAvatarEvent, false) assertThat(youChangedRoomAvatar).isEqualTo("You changed the room avatar") - val someoneChangedRoomAvatarEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = changedContent) + val someoneChangedRoomAvatarEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = changedContent) val someoneChangedRoomAvatar = formatter.format(someoneChangedRoomAvatarEvent, false) assertThat(someoneChangedRoomAvatar).isEqualTo("$otherName changed the room avatar") - val youRemovedRoomAvatarEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = removedContent) + val youRemovedRoomAvatarEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = removedContent) val youRemovedRoomAvatar = formatter.format(youRemovedRoomAvatarEvent, false) assertThat(youRemovedRoomAvatar).isEqualTo("You removed the room avatar") - val someoneRemovedRoomAvatarEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = removedContent) + val someoneRemovedRoomAvatarEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = removedContent) val someoneRemovedRoomAvatar = formatter.format(someoneRemovedRoomAvatarEvent, false) assertThat(someoneRemovedRoomAvatar).isEqualTo("$otherName removed the room avatar") } @@ -627,11 +627,11 @@ class DefaultBaseRoomLastMessageFormatterTest { val otherName = "Other" val content = StateContent("", OtherState.RoomCreate) - val youCreatedRoomMessage = createRoomEvent(sentByYou = true, senderDisplayName = null, content = content) + val youCreatedRoomMessage = createLatestEvent(sentByYou = true, senderDisplayName = null, content = content) val youCreatedRoom = formatter.format(youCreatedRoomMessage, false) assertThat(youCreatedRoom).isEqualTo("You created the room") - val someoneCreatedRoomEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = content) + val someoneCreatedRoomEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = content) val someoneCreatedRoom = formatter.format(someoneCreatedRoomEvent, false) assertThat(someoneCreatedRoom).isEqualTo("$otherName created the room") } @@ -642,11 +642,11 @@ class DefaultBaseRoomLastMessageFormatterTest { val otherName = "Other" val content = StateContent("", OtherState.RoomEncryption) - val youCreatedRoomMessage = createRoomEvent(sentByYou = true, senderDisplayName = null, content = content) + val youCreatedRoomMessage = createLatestEvent(sentByYou = true, senderDisplayName = null, content = content) val youCreatedRoom = formatter.format(youCreatedRoomMessage, false) assertThat(youCreatedRoom).isEqualTo("Encryption enabled") - val someoneCreatedRoomEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = content) + val someoneCreatedRoomEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = content) val someoneCreatedRoom = formatter.format(someoneCreatedRoomEvent, false) assertThat(someoneCreatedRoom).isEqualTo("Encryption enabled") } @@ -659,19 +659,19 @@ class DefaultBaseRoomLastMessageFormatterTest { val changedContent = StateContent("", OtherState.RoomName(newName)) val removedContent = StateContent("", OtherState.RoomName(null)) - val youChangedRoomNameEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = changedContent) + val youChangedRoomNameEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = changedContent) val youChangedRoomName = formatter.format(youChangedRoomNameEvent, false) assertThat(youChangedRoomName).isEqualTo("You changed the room name to: $newName") - val someoneChangedRoomNameEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = changedContent) + val someoneChangedRoomNameEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = changedContent) val someoneChangedRoomName = formatter.format(someoneChangedRoomNameEvent, false) assertThat(someoneChangedRoomName).isEqualTo("$otherName changed the room name to: $newName") - val youRemovedRoomNameEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = removedContent) + val youRemovedRoomNameEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = removedContent) val youRemovedRoomName = formatter.format(youRemovedRoomNameEvent, false) assertThat(youRemovedRoomName).isEqualTo("You removed the room name") - val someoneRemovedRoomNameEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = removedContent) + val someoneRemovedRoomNameEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = removedContent) val someoneRemovedRoomName = formatter.format(someoneRemovedRoomNameEvent, false) assertThat(someoneRemovedRoomName).isEqualTo("$otherName removed the room name") } @@ -684,19 +684,19 @@ class DefaultBaseRoomLastMessageFormatterTest { val changedContent = StateContent("", OtherState.RoomThirdPartyInvite(inviteeName)) val removedContent = StateContent("", OtherState.RoomThirdPartyInvite(null)) - val youInvitedSomeoneEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = changedContent) + val youInvitedSomeoneEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = changedContent) val youInvitedSomeone = formatter.format(youInvitedSomeoneEvent, false) assertThat(youInvitedSomeone).isEqualTo("You sent an invitation to $inviteeName to join the room") - val someoneInvitedSomeoneEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = changedContent) + val someoneInvitedSomeoneEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = changedContent) val someoneInvitedSomeone = formatter.format(someoneInvitedSomeoneEvent, false) assertThat(someoneInvitedSomeone).isEqualTo("$otherName sent an invitation to $inviteeName to join the room") - val youInvitedNoOneEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = removedContent) + val youInvitedNoOneEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = removedContent) val youInvitedNoOne = formatter.format(youInvitedNoOneEvent, false) assertThat(youInvitedNoOne).isNull() - val someoneInvitedNoOneEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = removedContent) + val someoneInvitedNoOneEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = removedContent) val someoneInvitedNoOne = formatter.format(someoneInvitedNoOneEvent, false) assertThat(someoneInvitedNoOne).isNull() } @@ -710,27 +710,27 @@ class DefaultBaseRoomLastMessageFormatterTest { val removedContent = StateContent("", OtherState.RoomTopic(null)) val blankContent = StateContent("", OtherState.RoomTopic("")) - val youChangedRoomTopicEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = changedContent) + val youChangedRoomTopicEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = changedContent) val youChangedRoomTopic = formatter.format(youChangedRoomTopicEvent, false) assertThat(youChangedRoomTopic).isEqualTo("You changed the topic to: $roomTopic") - val someoneChangedRoomTopicEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = changedContent) + val someoneChangedRoomTopicEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = changedContent) val someoneChangedRoomTopic = formatter.format(someoneChangedRoomTopicEvent, false) assertThat(someoneChangedRoomTopic).isEqualTo("$otherName changed the topic to: $roomTopic") - val youRemovedRoomTopicEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = removedContent) + val youRemovedRoomTopicEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = removedContent) val youRemovedRoomTopic = formatter.format(youRemovedRoomTopicEvent, false) assertThat(youRemovedRoomTopic).isEqualTo("You removed the room topic") - val someoneRemovedRoomTopicEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = removedContent) + val someoneRemovedRoomTopicEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = removedContent) val someoneRemovedRoomTopic = formatter.format(someoneRemovedRoomTopicEvent, false) assertThat(someoneRemovedRoomTopic).isEqualTo("$otherName removed the room topic") - val youSetBlankRoomTopicEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = blankContent) + val youSetBlankRoomTopicEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = blankContent) val youSetBlankRoomTopic = formatter.format(youSetBlankRoomTopicEvent, false) assertThat(youSetBlankRoomTopic).isEqualTo("You removed the room topic") - val someoneSetBlankRoomTopicEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = blankContent) + val someoneSetBlankRoomTopicEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = blankContent) val someoneSetBlankRoomTopic = formatter.format(someoneSetBlankRoomTopicEvent, false) assertThat(someoneSetBlankRoomTopic).isEqualTo("$otherName removed the room topic") } @@ -758,7 +758,7 @@ class DefaultBaseRoomLastMessageFormatterTest { val results = otherStates.map { state -> val content = StateContent("", state) - val event = createRoomEvent(sentByYou = false, senderDisplayName = "Someone", content = content) + val event = createLatestEvent(sentByYou = false, senderDisplayName = "Someone", content = content) val result = formatter.format(event, false) state to result } @@ -780,35 +780,35 @@ class DefaultBaseRoomLastMessageFormatterTest { val invalidContent = aProfileChangeMessageContent(avatarUrl = null, prevAvatarUrl = null) val sameContent = aProfileChangeMessageContent(avatarUrl = "same_avatar_url", prevAvatarUrl = "same_avatar_url") - val youChangedAvatarEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = changedContent) + val youChangedAvatarEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = changedContent) val youChangedAvatar = formatter.format(youChangedAvatarEvent, false) assertThat(youChangedAvatar).isEqualTo("You changed your avatar") - val someoneChangeAvatarEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = changedContent) + val someoneChangeAvatarEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = changedContent) val someoneChangeAvatar = formatter.format(someoneChangeAvatarEvent, false) assertThat(someoneChangeAvatar).isEqualTo("$otherName changed their avatar") - val youSetAvatarEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = setContent) + val youSetAvatarEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = setContent) val youSetAvatar = formatter.format(youSetAvatarEvent, false) assertThat(youSetAvatar).isEqualTo("You changed your avatar") - val someoneSetAvatarEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = setContent) + val someoneSetAvatarEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = setContent) val someoneSetAvatar = formatter.format(someoneSetAvatarEvent, false) assertThat(someoneSetAvatar).isEqualTo("$otherName changed their avatar") - val youRemovedAvatarEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = removedContent) + val youRemovedAvatarEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = removedContent) val youRemovedAvatar = formatter.format(youRemovedAvatarEvent, false) assertThat(youRemovedAvatar).isEqualTo("You changed your avatar") - val someoneRemovedAvatarEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = removedContent) + val someoneRemovedAvatarEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = removedContent) val someoneRemovedAvatar = formatter.format(someoneRemovedAvatarEvent, false) assertThat(someoneRemovedAvatar).isEqualTo("$otherName changed their avatar") - val unchangedEvent = createRoomEvent(sentByYou = true, senderDisplayName = otherName, content = sameContent) + val unchangedEvent = createLatestEvent(sentByYou = true, senderDisplayName = otherName, content = sameContent) val unchangedResult = formatter.format(unchangedEvent, false) assertThat(unchangedResult).isNull() - val invalidEvent = createRoomEvent(sentByYou = true, senderDisplayName = otherName, content = invalidContent) + val invalidEvent = createLatestEvent(sentByYou = true, senderDisplayName = otherName, content = invalidContent) val invalidResult = formatter.format(invalidEvent, false) assertThat(invalidResult).isNull() } @@ -825,35 +825,35 @@ class DefaultBaseRoomLastMessageFormatterTest { val sameContent = aProfileChangeMessageContent(displayName = newDisplayName, prevDisplayName = newDisplayName) val invalidContent = aProfileChangeMessageContent(displayName = null, prevDisplayName = null) - val youChangedDisplayNameEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = changedContent) + val youChangedDisplayNameEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = changedContent) val youChangedDisplayName = formatter.format(youChangedDisplayNameEvent, false) assertThat(youChangedDisplayName).isEqualTo("You changed your display name from $oldDisplayName to $newDisplayName") - val someoneChangedDisplayNameEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = changedContent) + val someoneChangedDisplayNameEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = changedContent) val someoneChangedDisplayName = formatter.format(someoneChangedDisplayNameEvent, false) assertThat(someoneChangedDisplayName).isEqualTo("$someoneElseId changed their display name from $oldDisplayName to $newDisplayName") - val youSetDisplayNameEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = setContent) + val youSetDisplayNameEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = setContent) val youSetDisplayName = formatter.format(youSetDisplayNameEvent, false) assertThat(youSetDisplayName).isEqualTo("You set your display name to $newDisplayName") - val someoneSetDisplayNameEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = setContent) + val someoneSetDisplayNameEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = setContent) val someoneSetDisplayName = formatter.format(someoneSetDisplayNameEvent, false) assertThat(someoneSetDisplayName).isEqualTo("$someoneElseId set their display name to $newDisplayName") - val youRemovedDisplayNameEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = removedContent) + val youRemovedDisplayNameEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = removedContent) val youRemovedDisplayName = formatter.format(youRemovedDisplayNameEvent, false) assertThat(youRemovedDisplayName).isEqualTo("You removed your display name (it was $oldDisplayName)") - val someoneRemovedDisplayNameEvent = createRoomEvent(sentByYou = false, senderDisplayName = otherName, content = removedContent) + val someoneRemovedDisplayNameEvent = createLatestEvent(sentByYou = false, senderDisplayName = otherName, content = removedContent) val someoneRemovedDisplayName = formatter.format(someoneRemovedDisplayNameEvent, false) assertThat(someoneRemovedDisplayName).isEqualTo("$someoneElseId removed their display name (it was $oldDisplayName)") - val unchangedEvent = createRoomEvent(sentByYou = true, senderDisplayName = otherName, content = sameContent) + val unchangedEvent = createLatestEvent(sentByYou = true, senderDisplayName = otherName, content = sameContent) val unchangedResult = formatter.format(unchangedEvent, false) assertThat(unchangedResult).isNull() - val invalidEvent = createRoomEvent(sentByYou = true, senderDisplayName = otherName, content = invalidContent) + val invalidEvent = createLatestEvent(sentByYou = true, senderDisplayName = otherName, content = invalidContent) val invalidResult = formatter.format(invalidEvent, false) assertThat(invalidResult).isNull() } @@ -882,15 +882,15 @@ class DefaultBaseRoomLastMessageFormatterTest { prevAvatarUrl = "same_avatar_url", ) - val youChangedBothEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = changedContent) + val youChangedBothEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = changedContent) val youChangedBoth = formatter.format(youChangedBothEvent, false) assertThat(youChangedBoth).isEqualTo("You changed your display name from $oldDisplayName to $newDisplayName\n(avatar was changed too)") - val invalidContentEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = invalidContent) + val invalidContentEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = invalidContent) val invalidMessage = formatter.format(invalidContentEvent, false) assertThat(invalidMessage).isNull() - val sameContentEvent = createRoomEvent(sentByYou = true, senderDisplayName = null, content = sameContent) + val sameContentEvent = createLatestEvent(sentByYou = true, senderDisplayName = null, content = sameContent) val sameMessage = formatter.format(sameContentEvent, false) assertThat(sameMessage).isNull() } @@ -904,10 +904,10 @@ class DefaultBaseRoomLastMessageFormatterTest { fun `Computes last message for poll in DM`() { val pollContent = aPollContent() - val mineContentEvent = createRoomEvent(sentByYou = true, senderDisplayName = "Alice", content = pollContent) + val mineContentEvent = createLatestEvent(sentByYou = true, senderDisplayName = "Alice", content = pollContent) assertThat(formatter.format(mineContentEvent, true)).isEqualTo("Poll: Do you like polls?") - val contentEvent = createRoomEvent(sentByYou = false, senderDisplayName = "Bob", content = pollContent) + val contentEvent = createLatestEvent(sentByYou = false, senderDisplayName = "Bob", content = pollContent) assertThat(formatter.format(contentEvent, true)).isEqualTo("Poll: Do you like polls?") } @@ -916,26 +916,26 @@ class DefaultBaseRoomLastMessageFormatterTest { fun `Computes last message for poll in room`() { val pollContent = aPollContent() - val mineContentEvent = createRoomEvent(sentByYou = true, senderDisplayName = "Alice", content = pollContent) + val mineContentEvent = createLatestEvent(sentByYou = true, senderDisplayName = "Alice", content = pollContent) assertThat(formatter.format(mineContentEvent, false).toString()).isEqualTo("You: Poll: Do you like polls?") - val contentEvent = createRoomEvent(sentByYou = false, senderDisplayName = "Bob", content = pollContent) + val contentEvent = createLatestEvent(sentByYou = false, senderDisplayName = "Bob", content = pollContent) assertThat(formatter.format(contentEvent, false).toString()).isEqualTo("Bob: Poll: Do you like polls?") } // endregion - private fun createRoomEvent( + private fun createLatestEvent( sentByYou: Boolean, senderDisplayName: String?, content: EventContent, - ): EventTimelineItem { + ): LatestEventValue { val sender = if (sentByYou) A_USER_ID else someoneElseId - val profile = aProfileTimelineDetails(senderDisplayName) - return anEventTimelineItem( - content = content, + val profile = aProfileDetails(senderDisplayName) + return aRemoteLatestEvent( + senderId = sender, senderProfile = profile, - sender = sender, + content = content, isOwn = sentByYou, ) } diff --git a/libraries/eventformatter/test/src/main/kotlin/io/element/android/libraries/eventformatter/test/FakeRoomLastMessageFormatter.kt b/libraries/eventformatter/test/src/main/kotlin/io/element/android/libraries/eventformatter/test/FakeRoomLatestEventFormatter.kt similarity index 59% rename from libraries/eventformatter/test/src/main/kotlin/io/element/android/libraries/eventformatter/test/FakeRoomLastMessageFormatter.kt rename to libraries/eventformatter/test/src/main/kotlin/io/element/android/libraries/eventformatter/test/FakeRoomLatestEventFormatter.kt index b5c069cff1..d82128b2d3 100644 --- a/libraries/eventformatter/test/src/main/kotlin/io/element/android/libraries/eventformatter/test/FakeRoomLastMessageFormatter.kt +++ b/libraries/eventformatter/test/src/main/kotlin/io/element/android/libraries/eventformatter/test/FakeRoomLatestEventFormatter.kt @@ -8,13 +8,13 @@ package io.element.android.libraries.eventformatter.test -import io.element.android.libraries.eventformatter.api.RoomLastMessageFormatter -import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem +import io.element.android.libraries.eventformatter.api.RoomLatestEventFormatter +import io.element.android.libraries.matrix.api.roomlist.LatestEventValue -class FakeRoomLastMessageFormatter : RoomLastMessageFormatter { +class FakeRoomLatestEventFormatter : RoomLatestEventFormatter { private var result: CharSequence? = null - override fun format(event: EventTimelineItem, isDmRoom: Boolean): CharSequence? { + override fun format(latestEvent: LatestEventValue, isDmRoom: Boolean): CharSequence? { return result } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/message/RoomMessage.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/message/RoomMessage.kt deleted file mode 100644 index 02aafb2e98..0000000000 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/room/message/RoomMessage.kt +++ /dev/null @@ -1,20 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-2025 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.libraries.matrix.api.room.message - -import io.element.android.libraries.matrix.api.core.EventId -import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem - -data class RoomMessage( - val eventId: EventId, - val event: EventTimelineItem, - val sender: UserId, - val originServerTs: Long, -) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/LatestEventValue.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/LatestEventValue.kt new file mode 100644 index 0000000000..5482a67875 --- /dev/null +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/LatestEventValue.kt @@ -0,0 +1,31 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.matrix.api.roomlist + +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.timeline.item.event.EventContent +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails + +sealed interface LatestEventValue { + data object None : LatestEventValue + data class Remote( + val timestamp: Long, + val content: EventContent, + val senderId: UserId, + val senderProfile: ProfileDetails, + val isOwn: Boolean, + ) : LatestEventValue + + data class Local( + val timestamp: Long, + val content: EventContent, + val senderId: UserId, + val senderProfile: ProfileDetails, + val isSending: Boolean, + ) : LatestEventValue +} diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomSummary.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomSummary.kt index 50af91a36c..89a4acfec1 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomSummary.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/roomlist/RoomSummary.kt @@ -9,13 +9,16 @@ package io.element.android.libraries.matrix.api.roomlist import io.element.android.libraries.matrix.api.room.RoomInfo -import io.element.android.libraries.matrix.api.room.message.RoomMessage data class RoomSummary( val info: RoomInfo, - val lastMessage: RoomMessage?, + val latestEvent: LatestEventValue, ) { val roomId = info.id - val lastMessageTimestamp = lastMessage?.originServerTs + val latestEventTimestamp = when (latestEvent) { + is LatestEventValue.None -> null + is LatestEventValue.Local -> latestEvent.timestamp + is LatestEventValue.Remote -> latestEvent.timestamp + } val isOneToOne get() = info.activeMembersCount == 2L } diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/ThreadSummary.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/ThreadSummary.kt index 8b2b0d101e..97923995a0 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/ThreadSummary.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/ThreadSummary.kt @@ -13,7 +13,7 @@ import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.timeline.item.event.EventContent import io.element.android.libraries.matrix.api.timeline.item.event.EventOrTransactionId -import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails sealed interface EventThreadInfo { data class ThreadRoot(val summary: ThreadSummary) : EventThreadInfo @@ -29,6 +29,6 @@ data class EmbeddedEventInfo( val eventOrTransactionId: EventOrTransactionId, val content: EventContent, val senderId: UserId, - val senderProfile: ProfileTimelineDetails, + val senderProfile: ProfileDetails, val timestamp: Long, ) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventTimelineItem.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventTimelineItem.kt index ba63a11c4c..8294b78c24 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventTimelineItem.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/EventTimelineItem.kt @@ -27,7 +27,7 @@ data class EventTimelineItem( val reactions: ImmutableList, val receipts: ImmutableList, val sender: UserId, - val senderProfile: ProfileTimelineDetails, + val senderProfile: ProfileDetails, val timestamp: Long, val content: EventContent, val origin: TimelineItemEventOrigin?, diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/InReplyTo.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/InReplyTo.kt index e9a12d82a3..43a54602ca 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/InReplyTo.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/InReplyTo.kt @@ -25,7 +25,7 @@ sealed interface InReplyTo { val eventId: EventId, val content: EventContent, val senderId: UserId, - val senderProfile: ProfileTimelineDetails, + val senderProfile: ProfileDetails, ) : InReplyTo /** diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/ProfileTimelineDetails.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/ProfileDetails.kt similarity index 68% rename from libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/ProfileTimelineDetails.kt rename to libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/ProfileDetails.kt index dee7290c98..6393a27bb2 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/ProfileTimelineDetails.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/ProfileDetails.kt @@ -12,20 +12,20 @@ import androidx.compose.runtime.Immutable import io.element.android.libraries.matrix.api.core.UserId @Immutable -sealed interface ProfileTimelineDetails { - data object Unavailable : ProfileTimelineDetails +sealed interface ProfileDetails { + data object Unavailable : ProfileDetails - data object Pending : ProfileTimelineDetails + data object Pending : ProfileDetails data class Ready( val displayName: String?, val displayNameAmbiguous: Boolean, val avatarUrl: String? - ) : ProfileTimelineDetails + ) : ProfileDetails data class Error( val message: String - ) : ProfileTimelineDetails + ) : ProfileDetails } /** @@ -34,9 +34,9 @@ sealed interface ProfileTimelineDetails { * If the display name is ambiguous, the user ID is appended in parentheses. * Otherwise, the display name is returned. */ -fun ProfileTimelineDetails.getDisambiguatedDisplayName(userId: UserId): String { +fun ProfileDetails.getDisambiguatedDisplayName(userId: UserId): String { return when (this) { - is ProfileTimelineDetails.Ready -> when { + is ProfileDetails.Ready -> when { displayName == null -> userId.value displayNameAmbiguous -> "$displayName ($userId)" else -> displayName @@ -45,16 +45,16 @@ fun ProfileTimelineDetails.getDisambiguatedDisplayName(userId: UserId): String { } } -fun ProfileTimelineDetails.getDisplayName(): String? { +fun ProfileDetails.getDisplayName(): String? { return when (this) { - is ProfileTimelineDetails.Ready -> displayName + is ProfileDetails.Ready -> displayName else -> null } } -fun ProfileTimelineDetails.getAvatarUrl(): String? { +fun ProfileDetails.getAvatarUrl(): String? { return when (this) { - is ProfileTimelineDetails.Ready -> avatarUrl + is ProfileDetails.Ready -> avatarUrl else -> null } } diff --git a/libraries/matrix/api/src/test/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/ProfileTimelineDetailsTest.kt b/libraries/matrix/api/src/test/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/ProfileTimelineDetailsTest.kt index 4fa764adce..ffb59ba7d1 100644 --- a/libraries/matrix/api/src/test/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/ProfileTimelineDetailsTest.kt +++ b/libraries/matrix/api/src/test/kotlin/io/element/android/libraries/matrix/api/timeline/item/event/ProfileTimelineDetailsTest.kt @@ -18,23 +18,23 @@ private val aUserId = UserId(A_USER_ID) class ProfileTimelineDetailsTest { @Test fun `getDisambiguatedDisplayName of Unavailable should be equal to userId`() { - assertThat(ProfileTimelineDetails.Unavailable.getDisambiguatedDisplayName(aUserId)).isEqualTo(A_USER_ID) + assertThat(ProfileDetails.Unavailable.getDisambiguatedDisplayName(aUserId)).isEqualTo(A_USER_ID) } @Test fun `getDisambiguatedDisplayName of Error should be equal to userId`() { - assertThat(ProfileTimelineDetails.Error("An error").getDisambiguatedDisplayName(aUserId)).isEqualTo(A_USER_ID) + assertThat(ProfileDetails.Error("An error").getDisambiguatedDisplayName(aUserId)).isEqualTo(A_USER_ID) } @Test fun `getDisambiguatedDisplayName of Pending should be equal to userId`() { - assertThat(ProfileTimelineDetails.Pending.getDisambiguatedDisplayName(aUserId)).isEqualTo(A_USER_ID) + assertThat(ProfileDetails.Pending.getDisambiguatedDisplayName(aUserId)).isEqualTo(A_USER_ID) } @Test fun `getDisambiguatedDisplayName of Ready without display name should be equal to userId`() { assertThat( - ProfileTimelineDetails.Ready( + ProfileDetails.Ready( displayName = null, displayNameAmbiguous = false, avatarUrl = null, @@ -45,7 +45,7 @@ class ProfileTimelineDetailsTest { @Test fun `getDisambiguatedDisplayName of Ready with display name should be equal to display name`() { assertThat( - ProfileTimelineDetails.Ready( + ProfileDetails.Ready( displayName = "Alice", displayNameAmbiguous = false, avatarUrl = null, @@ -56,7 +56,7 @@ class ProfileTimelineDetailsTest { @Test fun `getDisambiguatedDisplayName of Ready with display name and ambiguous should be equal to display name with user id`() { assertThat( - ProfileTimelineDetails.Ready( + ProfileDetails.Ready( displayName = "Alice", displayNameAmbiguous = true, avatarUrl = null, diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/message/RoomMessageFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/message/RoomMessageFactory.kt deleted file mode 100644 index d03cf013a4..0000000000 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/message/RoomMessageFactory.kt +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2025 Element Creations Ltd. - * Copyright 2023-2025 New Vector Ltd. - * - * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. - * Please see LICENSE files in the repository root for full details. - */ - -package io.element.android.libraries.matrix.impl.room.message - -import io.element.android.libraries.matrix.api.room.message.RoomMessage -import io.element.android.libraries.matrix.impl.timeline.item.event.EventTimelineItemMapper -import org.matrix.rustcomponents.sdk.EventTimelineItem as RustEventTimelineItem - -class RoomMessageFactory( - private val eventTimelineItemMapper: EventTimelineItemMapper = EventTimelineItemMapper(), -) { - fun create(eventTimelineItem: RustEventTimelineItem?): RoomMessage? { - eventTimelineItem ?: return null - val mappedTimelineItem = eventTimelineItemMapper.map(eventTimelineItem) - return RoomMessage( - eventId = mappedTimelineItem.eventId ?: return null, - event = mappedTimelineItem, - sender = mappedTimelineItem.sender, - originServerTs = mappedTimelineItem.timestamp, - ) - } -} diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt index b0d545e2a1..4e342f3a48 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt @@ -40,7 +40,7 @@ internal class RoomListFactory( private val sessionCoroutineScope: CoroutineScope, private val analyticsService: AnalyticsService, ) { - private val roomSummaryDetailsFactory: RoomSummaryFactory = RoomSummaryFactory() + private val roomSummaryFactory: RoomSummaryFactory = RoomSummaryFactory() /** * Creates a room list that can be used to load more rooms and filter them dynamically. @@ -55,7 +55,7 @@ internal class RoomListFactory( val loadingStateFlow: MutableStateFlow = MutableStateFlow(RoomList.LoadingState.NotLoaded) val filteredSummariesFlow = MutableSharedFlow>(replay = 1, extraBufferCapacity = 1) val summariesFlow = MutableSharedFlow>(replay = 1, extraBufferCapacity = 1) - val processor = RoomSummaryListProcessor(summariesFlow, innerRoomListService, coroutineContext, roomSummaryDetailsFactory) + val processor = RoomSummaryListProcessor(summariesFlow, innerRoomListService, coroutineContext, roomSummaryFactory) // Makes sure we don't miss any events val dynamicEvents = MutableSharedFlow(replay = 100) val currentFilter = MutableStateFlow(initialFilter) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryFactory.kt index de4f09ada6..3d5efedd54 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryFactory.kt @@ -8,24 +8,44 @@ package io.element.android.libraries.matrix.impl.roomlist +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.roomlist.LatestEventValue import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.impl.room.RoomInfoMapper -import io.element.android.libraries.matrix.impl.room.message.RoomMessageFactory +import io.element.android.libraries.matrix.impl.timeline.item.event.TimelineEventContentMapper +import io.element.android.libraries.matrix.impl.timeline.item.event.map import org.matrix.rustcomponents.sdk.Room import org.matrix.rustcomponents.sdk.use +import org.matrix.rustcomponents.sdk.LatestEventValue as RustLatestEventValue class RoomSummaryFactory( - private val roomMessageFactory: RoomMessageFactory = RoomMessageFactory(), + private val contentMapper: TimelineEventContentMapper = TimelineEventContentMapper(), private val roomInfoMapper: RoomInfoMapper = RoomInfoMapper(), ) { suspend fun create(room: Room): RoomSummary { val roomInfo = room.roomInfo().let(roomInfoMapper::map) - val latestRoomMessage = room.latestEvent().use { event -> - roomMessageFactory.create(event) + val latestEvent = room.newLatestEvent().use { event -> + when (event) { + is RustLatestEventValue.None -> LatestEventValue.None + is RustLatestEventValue.Local -> LatestEventValue.Local( + timestamp = event.timestamp.toLong(), + content = contentMapper.map(event.content), + isSending = event.isSending, + senderId = UserId(event.sender), + senderProfile = event.profile.map(), + ) + is RustLatestEventValue.Remote -> LatestEventValue.Remote( + timestamp = event.timestamp.toLong(), + content = contentMapper.map(event.content), + senderId = UserId(event.sender), + senderProfile = event.profile.map(), + isOwn = event.isOwn, + ) + } } return RoomSummary( info = roomInfo, - lastMessage = latestRoomMessage, + latestEvent = latestEvent, ) } } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt index c99e2b5448..3f5a919139 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessor.kt @@ -24,7 +24,7 @@ class RoomSummaryListProcessor( private val roomSummaries: MutableSharedFlow>, private val roomListService: RoomListServiceInterface, private val coroutineContext: CoroutineContext, - private val roomSummaryDetailsFactory: RoomSummaryFactory = RoomSummaryFactory(), + private val roomSummaryFactory: RoomSummaryFactory, ) { private val mutex = Mutex() @@ -103,7 +103,7 @@ class RoomSummaryListProcessor( } private suspend fun buildSummaryForRoomListEntry(entry: Room): RoomSummary { - return entry.use { roomSummaryDetailsFactory.create(room = it) } + return entry.use { roomSummaryFactory.create(room = it) } } private suspend fun buildRoomSummaryForIdentifier(identifier: String): RoomSummary? { diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventTimelineItemMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventTimelineItemMapper.kt index 68b8c7a8bb..6715169899 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventTimelineItemMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/timeline/item/event/EventTimelineItemMapper.kt @@ -17,7 +17,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.EventReaction import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem import io.element.android.libraries.matrix.api.timeline.item.event.LocalEventSendState import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield -import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails import io.element.android.libraries.matrix.api.timeline.item.event.ReactionSender import io.element.android.libraries.matrix.api.timeline.item.event.Receipt import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin @@ -64,12 +64,12 @@ class EventTimelineItemMapper( } } -fun RustProfileDetails.map(): ProfileTimelineDetails { +fun RustProfileDetails.map(): ProfileDetails { return when (this) { - RustProfileDetails.Pending -> ProfileTimelineDetails.Pending - RustProfileDetails.Unavailable -> ProfileTimelineDetails.Unavailable - is RustProfileDetails.Error -> ProfileTimelineDetails.Error(message) - is RustProfileDetails.Ready -> ProfileTimelineDetails.Ready( + RustProfileDetails.Pending -> ProfileDetails.Pending + RustProfileDetails.Unavailable -> ProfileDetails.Unavailable + is RustProfileDetails.Error -> ProfileDetails.Error(message) + is RustProfileDetails.Ready -> ProfileDetails.Ready( displayName = displayName, displayNameAmbiguous = displayNameAmbiguous, avatarUrl = avatarUrl diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt index 9c84ccc559..eaa62abb65 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomSummaryListProcessorTest.kt @@ -192,6 +192,6 @@ class RoomSummaryListProcessorTest { summaries, FakeFfiRoomListService(), coroutineContext = StandardTestDispatcher(testScheduler), - roomSummaryDetailsFactory = RoomSummaryFactory(), + roomSummaryFactory = RoomSummaryFactory(), ) } diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/LatestEventValueFixture.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/LatestEventValueFixture.kt new file mode 100644 index 0000000000..32d6cc927c --- /dev/null +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/LatestEventValueFixture.kt @@ -0,0 +1,48 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.libraries.matrix.test.room + +import io.element.android.libraries.matrix.api.core.UserId +import io.element.android.libraries.matrix.api.roomlist.LatestEventValue +import io.element.android.libraries.matrix.api.timeline.item.event.EventContent +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails +import io.element.android.libraries.matrix.test.A_USER_ID +import io.element.android.libraries.matrix.test.timeline.aMessageContent +import io.element.android.libraries.matrix.test.timeline.aProfileDetails + +fun aRemoteLatestEvent( + content: EventContent = aMessageContent(), + timestamp: Long = 0L, + isOwn: Boolean = false, + senderId: UserId = A_USER_ID, + senderProfile: ProfileDetails = aProfileDetails(), +): LatestEventValue.Remote { + return LatestEventValue.Remote( + timestamp = timestamp, + content = content, + senderId = senderId, + senderProfile = senderProfile, + isOwn = isOwn, + ) +} + +fun aLocalLatestEvent( + content: EventContent = aMessageContent(), + timestamp: Long = 0L, + isSending: Boolean = false, + senderId: UserId = A_USER_ID, + senderProfile: ProfileDetails = aProfileDetails(), +): LatestEventValue.Local { + return LatestEventValue.Local( + timestamp = timestamp, + content = content, + senderId = senderId, + senderProfile = senderProfile, + isSending = isSending, + ) +} diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt index 45715cbd27..8568e3c916 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/room/RoomSummaryFixture.kt @@ -18,28 +18,24 @@ import io.element.android.libraries.matrix.api.room.RoomMember import io.element.android.libraries.matrix.api.room.RoomNotificationMode import io.element.android.libraries.matrix.api.room.history.RoomHistoryVisibility import io.element.android.libraries.matrix.api.room.join.JoinRule -import io.element.android.libraries.matrix.api.room.message.RoomMessage import io.element.android.libraries.matrix.api.room.powerlevels.RoomPowerLevels import io.element.android.libraries.matrix.api.room.tombstone.SuccessorRoom +import io.element.android.libraries.matrix.api.roomlist.LatestEventValue import io.element.android.libraries.matrix.api.roomlist.RoomSummary -import io.element.android.libraries.matrix.api.timeline.item.event.EventTimelineItem import io.element.android.libraries.matrix.api.user.MatrixUser -import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.A_ROOM_NAME import io.element.android.libraries.matrix.test.A_ROOM_RAW_NAME import io.element.android.libraries.matrix.test.A_ROOM_TOPIC -import io.element.android.libraries.matrix.test.A_USER_ID -import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem import kotlinx.collections.immutable.persistentMapOf import kotlinx.collections.immutable.toImmutableList fun aRoomSummary( info: RoomInfo = aRoomInfo(), - lastMessage: RoomMessage? = aRoomMessage(), + latestEventValue: LatestEventValue = aRemoteLatestEvent(), ) = RoomSummary( info = info, - lastMessage = lastMessage, + latestEvent = latestEventValue, ) fun aRoomSummary( @@ -79,7 +75,7 @@ fun aRoomSummary( numUnreadNotifications: Long = 0, numUnreadMentions: Long = 0, historyVisibility: RoomHistoryVisibility = RoomHistoryVisibility.Joined, - lastMessage: RoomMessage? = aRoomMessage(), + latestEvent: LatestEventValue = aRemoteLatestEvent(), roomVersion: String? = "11", privilegedCreatorRole: Boolean = false, ) = RoomSummary( @@ -120,17 +116,5 @@ fun aRoomSummary( roomVersion = roomVersion, privilegedCreatorRole = privilegedCreatorRole, ), - lastMessage = lastMessage, -) - -fun aRoomMessage( - eventId: EventId = AN_EVENT_ID, - event: EventTimelineItem = anEventTimelineItem(), - userId: UserId = A_USER_ID, - timestamp: Long = 0L, -) = RoomMessage( - eventId = eventId, - event = event, - sender = userId, - originServerTs = timestamp, + latestEvent = latestEvent, ) diff --git a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/TimelineFixture.kt b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/TimelineFixture.kt index e2e6192363..c8d8ff6015 100644 --- a/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/TimelineFixture.kt +++ b/libraries/matrix/test/src/main/kotlin/io/element/android/libraries/matrix/test/timeline/TimelineFixture.kt @@ -27,7 +27,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield import io.element.android.libraries.matrix.api.timeline.item.event.MessageType import io.element.android.libraries.matrix.api.timeline.item.event.PollContent import io.element.android.libraries.matrix.api.timeline.item.event.ProfileChangeContent -import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails import io.element.android.libraries.matrix.api.timeline.item.event.Receipt import io.element.android.libraries.matrix.api.timeline.item.event.SendHandleProvider import io.element.android.libraries.matrix.api.timeline.item.event.StickerContent @@ -53,7 +53,7 @@ fun anEventTimelineItem( reactions: ImmutableList = persistentListOf(), receipts: ImmutableList = persistentListOf(), sender: UserId = A_USER_ID, - senderProfile: ProfileTimelineDetails = aProfileTimelineDetails(), + senderProfile: ProfileDetails = aProfileDetails(), timestamp: Long = 0L, content: EventContent = aProfileChangeMessageContent(), debugInfoProvider: TimelineItemDebugInfoProvider = TimelineItemDebugInfoProvider { aTimelineItemDebugInfo() }, @@ -79,11 +79,11 @@ fun anEventTimelineItem( sendHandleProvider = sendHandleProvider, ) -fun aProfileTimelineDetails( +fun aProfileDetails( displayName: String? = A_USER_NAME, displayNameAmbiguous: Boolean = false, avatarUrl: String? = null -): ProfileTimelineDetails = ProfileTimelineDetails.Ready( +): ProfileDetails = ProfileDetails.Ready( displayName = displayName, displayNameAmbiguous = displayNameAmbiguous, avatarUrl = avatarUrl, diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetails.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetails.kt index 0d12866e8c..3179c748ea 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetails.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetails.kt @@ -15,7 +15,7 @@ import io.element.android.libraries.matrix.api.permalink.PermalinkParser import io.element.android.libraries.matrix.api.timeline.item.event.EventContent import io.element.android.libraries.matrix.api.timeline.item.event.InReplyTo import io.element.android.libraries.matrix.api.timeline.item.event.MessageContent -import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails import io.element.android.libraries.matrix.api.timeline.item.event.StickerContent import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType import io.element.android.libraries.matrix.ui.messages.toPlainText @@ -25,7 +25,7 @@ sealed interface InReplyToDetails { data class Ready( val eventId: EventId, val senderId: UserId, - val senderProfile: ProfileTimelineDetails, + val senderProfile: ProfileDetails, val eventContent: EventContent?, val textContent: String?, ) : InReplyToDetails diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailsProvider.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailsProvider.kt index 20fb717d7d..ac545ed8ea 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailsProvider.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailsProvider.kt @@ -24,7 +24,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.MessageConten import io.element.android.libraries.matrix.api.timeline.item.event.MessageType import io.element.android.libraries.matrix.api.timeline.item.event.NoticeMessageType import io.element.android.libraries.matrix.api.timeline.item.event.PollContent -import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails import io.element.android.libraries.matrix.api.timeline.item.event.RedactedContent import io.element.android.libraries.matrix.api.timeline.item.event.StickerMessageType import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageType @@ -161,7 +161,7 @@ fun aProfileTimelineDetailsReady( displayName: String? = "Sender", displayNameAmbiguous: Boolean = false, avatarUrl: String? = null, -) = ProfileTimelineDetails.Ready( +) = ProfileDetails.Ready( displayName = displayName, displayNameAmbiguous = displayNameAmbiguous, avatarUrl = avatarUrl, diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToView.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToView.kt index 6746c8ffdb..fc5d6577c7 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToView.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToView.kt @@ -42,7 +42,7 @@ import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Icon import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails import io.element.android.libraries.matrix.api.timeline.item.event.getDisambiguatedDisplayName import io.element.android.libraries.matrix.ui.components.AttachmentThumbnail import io.element.android.libraries.matrix.ui.messages.sender.SenderName @@ -74,7 +74,7 @@ fun InReplyToView( @Composable private fun ReplyToReadyContent( senderId: UserId, - senderProfile: ProfileTimelineDetails, + senderProfile: ProfileDetails, metadata: InReplyToMetadata?, modifier: Modifier = Modifier, ) { diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/sender/SenderName.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/sender/SenderName.kt index 582223fee6..cdca0937c1 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/sender/SenderName.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/sender/SenderName.kt @@ -23,13 +23,13 @@ import io.element.android.libraries.designsystem.preview.ElementPreview import io.element.android.libraries.designsystem.preview.PreviewsDayNight import io.element.android.libraries.designsystem.theme.components.Text import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails // https://www.figma.com/file/Ni6Ii8YKtmXCKYNE90cC67/Timeline-(new)?type=design&node-id=917-80169&mode=design&t=A0CJCBbMqR8NOwUQ-0 @Composable fun SenderName( senderId: UserId, - senderProfile: ProfileTimelineDetails, + senderProfile: ProfileDetails, senderNameMode: SenderNameMode, modifier: Modifier = Modifier, ) { @@ -39,12 +39,12 @@ fun SenderName( verticalAlignment = Alignment.CenterVertically, ) { when (senderProfile) { - is ProfileTimelineDetails.Error, - ProfileTimelineDetails.Pending, - ProfileTimelineDetails.Unavailable -> { + is ProfileDetails.Error, + ProfileDetails.Pending, + ProfileDetails.Unavailable -> { MainText(text = senderId.value, mode = senderNameMode) } - is ProfileTimelineDetails.Ready -> { + is ProfileDetails.Ready -> { val displayName = senderProfile.displayName if (displayName.isNullOrEmpty()) { MainText(text = senderId.value, mode = senderNameMode) @@ -121,7 +121,7 @@ internal fun SenderNamePreview( ) = ElementPreview { SenderName( senderId = senderNameData.userId, - senderProfile = senderNameData.profileTimelineDetails, + senderProfile = senderNameData.profileDetails, senderNameMode = senderNameData.senderNameMode, ) } diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/sender/SenderNameDataProvider.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/sender/SenderNameDataProvider.kt index af9366c474..96ad91b869 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/sender/SenderNameDataProvider.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/messages/sender/SenderNameDataProvider.kt @@ -11,11 +11,11 @@ package io.element.android.libraries.matrix.ui.messages.sender import androidx.compose.ui.graphics.Color import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.libraries.matrix.api.core.UserId -import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails data class SenderNameData( val userId: UserId, - val profileTimelineDetails: ProfileTimelineDetails, + val profileDetails: ProfileDetails, val senderNameMode: SenderNameMode, ) @@ -38,7 +38,7 @@ open class SenderNameDataProvider : PreviewParameterProvider { SenderNameData( senderNameMode = senderNameMode, userId = UserId("@alice:${senderNameMode.javaClass.simpleName.lowercase()}"), - profileTimelineDetails = ProfileTimelineDetails.Unavailable, + profileDetails = ProfileDetails.Unavailable, ), ) } @@ -49,7 +49,7 @@ private fun aSenderNameData( displayNameAmbiguous: Boolean = false, ) = SenderNameData( userId = UserId("@alice:${senderNameMode.javaClass.simpleName.lowercase()}"), - profileTimelineDetails = ProfileTimelineDetails.Ready( + profileDetails = ProfileDetails.Ready( displayName = "Alice ${senderNameMode.javaClass.simpleName}", displayNameAmbiguous = displayNameAmbiguous, avatarUrl = null diff --git a/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailTest.kt b/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailTest.kt index 6bbcf9127c..9507a30763 100644 --- a/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailTest.kt +++ b/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToDetailTest.kt @@ -18,7 +18,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.TextMessageTy import io.element.android.libraries.matrix.test.AN_EVENT_ID import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.permalink.FakePermalinkParser -import io.element.android.libraries.matrix.test.timeline.aProfileTimelineDetails +import io.element.android.libraries.matrix.test.timeline.aProfileDetails import io.element.android.libraries.matrix.test.timeline.item.event.aRoomMembershipContent import org.junit.Test @@ -47,7 +47,7 @@ class InReplyToDetailTest { val inReplyTo = InReplyTo.Ready( eventId = AN_EVENT_ID, senderId = A_USER_ID, - senderProfile = aProfileTimelineDetails(), + senderProfile = aProfileDetails(), content = aRoomMembershipContent( userId = A_USER_ID, change = MembershipChange.INVITED, @@ -65,7 +65,7 @@ class InReplyToDetailTest { val inReplyTo = InReplyTo.Ready( eventId = AN_EVENT_ID, senderId = A_USER_ID, - senderProfile = aProfileTimelineDetails(), + senderProfile = aProfileDetails(), content = MessageContent( body = "**Hello!**", inReplyTo = null, @@ -90,7 +90,7 @@ class InReplyToDetailTest { val inReplyTo = InReplyTo.Ready( eventId = AN_EVENT_ID, senderId = A_USER_ID, - senderProfile = aProfileTimelineDetails(), + senderProfile = aProfileDetails(), content = MessageContent( body = "**Hello!**", inReplyTo = null, diff --git a/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToMetadataKtTest.kt b/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToMetadataKtTest.kt index 67c3596af3..e7cae1151b 100644 --- a/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToMetadataKtTest.kt +++ b/libraries/matrixui/src/test/kotlin/io/element/android/libraries/matrix/ui/messages/reply/InReplyToMetadataKtTest.kt @@ -29,7 +29,7 @@ import io.element.android.libraries.matrix.api.timeline.item.event.ImageMessageT import io.element.android.libraries.matrix.api.timeline.item.event.LocationMessageType import io.element.android.libraries.matrix.api.timeline.item.event.OtherState import io.element.android.libraries.matrix.api.timeline.item.event.ProfileChangeContent -import io.element.android.libraries.matrix.api.timeline.item.event.ProfileTimelineDetails +import io.element.android.libraries.matrix.api.timeline.item.event.ProfileDetails import io.element.android.libraries.matrix.api.timeline.item.event.RedactedContent import io.element.android.libraries.matrix.api.timeline.item.event.StateContent import io.element.android.libraries.matrix.api.timeline.item.event.StickerContent @@ -42,7 +42,7 @@ import io.element.android.libraries.matrix.test.A_USER_ID import io.element.android.libraries.matrix.test.media.aMediaSource import io.element.android.libraries.matrix.test.timeline.aMessageContent import io.element.android.libraries.matrix.test.timeline.aPollContent -import io.element.android.libraries.matrix.test.timeline.aProfileTimelineDetails +import io.element.android.libraries.matrix.test.timeline.aProfileDetails import io.element.android.libraries.matrix.test.timeline.item.event.aRoomMembershipContent import io.element.android.libraries.matrix.ui.components.A_BLUR_HASH import io.element.android.libraries.matrix.ui.components.AttachmentThumbnailInfo @@ -549,7 +549,7 @@ class InReplyToMetadataKtTest { private fun anInReplyToDetailsReady( eventId: EventId = AN_EVENT_ID, senderId: UserId = A_USER_ID, - senderProfile: ProfileTimelineDetails = aProfileTimelineDetails(), + senderProfile: ProfileDetails = aProfileDetails(), eventContent: EventContent? = aMessageContent(), textContent: String? = "textContent", ) = InReplyToDetails.Ready( From 539aa35eeb496e5698a89dfc7dd2583fb6837265 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 11:57:22 +0100 Subject: [PATCH 064/113] fix(deps): update android.gradle.plugin to v8.13.1 (#5260) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * fix(deps): update android.gradle.plugin to v8.13.1 * Remove warning about AGP 8.12.x+ * Fix proguard-related code deprecations, use the new `optimization` API * Workaround issues related to Android lint not being able to check these complex methods with kotlin contracts --------- Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Jorge Martín --- app/build.gradle.kts | 18 ++++++--------- app/proguard-rules.pro | 23 +++++++++++++++++-- gradle.properties | 3 +++ gradle/libs.versions.toml | 3 +-- .../libraries/architecture/AsyncAction.kt | 8 +++---- .../libraries/architecture/AsyncData.kt | 11 ++++----- 6 files changed, 40 insertions(+), 26 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index 4026888ee2..2464155cb4 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -129,12 +129,12 @@ android { ) signingConfig = signingConfigs.getByName("debug") - postprocessing { - isRemoveUnusedCode = true - isObfuscate = false - isOptimizeCode = true - isRemoveUnusedResources = true - proguardFiles("proguard-rules.pro") + optimization { + enable = true + keepRules { + files.add(File(projectDir, "proguard-rules.pro")) + files.add(getDefaultProguardFile("proguard-android-optimize.txt")) + } } } @@ -152,10 +152,6 @@ android { matchingFallbacks += listOf("release") signingConfig = signingConfigs.getByName("nightly") - postprocessing { - initWith(release.postprocessing) - } - firebaseAppDistribution { artifactType = "APK" // We upload the universal APK to fix this error: @@ -341,7 +337,7 @@ fun Project.configureLicensesTasks(reportingExtension: ReportingExtension) { it.toString() } } - val artifactsFile = reportingExtension.file("licensee/android$capitalizedVariantName/artifacts.json") + val artifactsFile = reportingExtension.baseDirectory.file("licensee/android$capitalizedVariantName/artifacts.json") val copyArtifactsTask = project.tasks.register("copy${capitalizedVariantName}LicenseeReportToAssets") { diff --git a/app/proguard-rules.pro b/app/proguard-rules.pro index c55b1bf1c2..96109425fa 100644 --- a/app/proguard-rules.pro +++ b/app/proguard-rules.pro @@ -41,8 +41,6 @@ static int windowAttachCount(android.view.View); } --keep class io.element.android.x.di.** { *; } - # Keep LogSessionId class and related classes (https://github.com/androidx/media/issues/2535) -keep class android.media.metrics.LogSessionId { *; } @@ -51,3 +49,24 @@ # Keep Media3 classes that use reflection (https://github.com/androidx/media/issues/2535) -keep class androidx.media3.** { *; } -dontwarn android.media.metrics.** + +# New rules after AGP 8.13.1 upgrade +-dontwarn androidx.window.extensions.WindowExtensions +-dontwarn androidx.window.extensions.WindowExtensionsProvider +-dontwarn androidx.window.extensions.area.ExtensionWindowAreaPresentation +-dontwarn androidx.window.extensions.layout.DisplayFeature +-dontwarn androidx.window.extensions.layout.FoldingFeature +-dontwarn androidx.window.extensions.layout.WindowLayoutComponent +-dontwarn androidx.window.extensions.layout.WindowLayoutInfo +-dontwarn androidx.window.sidecar.SidecarDeviceState +-dontwarn androidx.window.sidecar.SidecarDisplayFeature +-dontwarn androidx.window.sidecar.SidecarInterface$SidecarCallback +-dontwarn androidx.window.sidecar.SidecarInterface +-dontwarn androidx.window.sidecar.SidecarProvider +-dontwarn androidx.window.sidecar.SidecarWindowLayoutInfo + +# Also needed after AGP 8.13.1 upgrade, it seems like proguard is now more aggressive on removing unused code +-keep class org.matrix.rustcomponents.sdk.** { *;} +-keep class uniffi.** { *;} +-keep class io.element.android.x.di.** { *; } +-keepnames class io.element.android.x.** diff --git a/gradle.properties b/gradle.properties index 5a73e519ad..ce03899940 100644 --- a/gradle.properties +++ b/gradle.properties @@ -59,3 +59,6 @@ detekt.use.worker.api=true # Let test include roborazzi verification # https://github.com/takahirom/roborazzi?tab=readme-ov-file#roborazzitest roborazzi.test.verify=true + +# Needed after enabling proguard on AGP 8.13.1 +android.r8.gradual.support=true diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 585220fb8d..c0bb446e87 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -3,8 +3,7 @@ [versions] # Project -# We cannot use 8.12.+ since it breaks F-Droid build (see https://github.com/element-hq/element-x-android/issues/3420#issuecomment-3199571010) -android_gradle_plugin = "8.11.1" +android_gradle_plugin = "8.13.1" # When updateing this, please also update the version in the file ./idea/kotlinc.xml kotlin = "2.2.20" kotlinpoet = "2.2.0" diff --git a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncAction.kt b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncAction.kt index db91316905..bb833162e3 100644 --- a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncAction.kt +++ b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncAction.kt @@ -155,16 +155,16 @@ inline fun MutableState>.runUpdatingStateNoSuccess( * @param resultBlock a suspending function that returns a [Result]. * @return the [Result] returned by [resultBlock]. */ -@OptIn(ExperimentalContracts::class) @Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE") suspend inline fun runUpdatingState( state: MutableState>, errorTransform: (Throwable) -> Throwable = { it }, resultBlock: suspend () -> Result, ): Result { - contract { - callsInPlace(resultBlock, InvocationKind.EXACTLY_ONCE) - } + // Restore when the issue with contracts and AGP 8.13.x is fixed +// contract { +// callsInPlace(resultBlock, InvocationKind.EXACTLY_ONCE) +// } state.value = AsyncAction.Loading return try { resultBlock() diff --git a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncData.kt b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncData.kt index 118addf1fe..734ff16692 100644 --- a/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncData.kt +++ b/libraries/architecture/src/main/kotlin/io/element/android/libraries/architecture/AsyncData.kt @@ -11,9 +11,6 @@ package io.element.android.libraries.architecture import androidx.compose.runtime.MutableState import androidx.compose.runtime.Stable import io.element.android.libraries.core.extensions.runCatchingExceptions -import kotlin.contracts.ExperimentalContracts -import kotlin.contracts.InvocationKind -import kotlin.contracts.contract /** * Sealed type that allows to model an asynchronous operation. @@ -134,16 +131,16 @@ suspend inline fun MutableState>.runUpdatingState( * @param resultBlock a suspending function that returns a [Result]. * @return the [Result] returned by [resultBlock]. */ -@OptIn(ExperimentalContracts::class) @Suppress("REDUNDANT_INLINE_SUSPEND_FUNCTION_TYPE") suspend inline fun runUpdatingState( state: MutableState>, errorTransform: (Throwable) -> Throwable = { it }, resultBlock: suspend () -> Result, ): Result { - contract { - callsInPlace(resultBlock, InvocationKind.EXACTLY_ONCE) - } + // Restore when the issue with contracts and AGP 8.13.x is fixed +// contract { +// callsInPlace(resultBlock, InvocationKind.EXACTLY_ONCE) +// } val prevData = state.value.dataOrNull() state.value = AsyncData.Loading(prevData = prevData) return resultBlock().fold( From c6ba2f5d10e87ea611d0678e1f2ddbd2eee7aafb Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 18 Nov 2025 21:19:08 +0100 Subject: [PATCH 065/113] change(security and privacy) : extract code to a separate module --- features/roomdetails/impl/build.gradle.kts | 2 + .../roomdetails/impl/RoomDetailsFlowNode.kt | 5 +- .../roomdetails/impl/RoomDetailsPresenter.kt | 2 +- .../impl/DefaultRoomDetailsEntryPointTest.kt | 2 + .../securityandprivacy/api/build.gradle.kts | 21 ++++++++ .../api/SecurityAndPrivacyEntryPoint.kt | 13 +++++ .../api}/SecurityAndPrivacyPermissions.kt | 4 +- .../securityandprivacy/impl/build.gradle.kts | 48 +++++++++++++++++++ .../DefaultSecurityAndPrivacyEntryPoint.kt | 23 +++++++++ .../impl}/SecurityAndPrivacyFlowNode.kt | 5 +- .../impl}/SecurityAndPrivacyNavigator.kt | 2 +- .../editroomaddress/EditRoomAddressEvents.kt | 2 +- .../editroomaddress/EditRoomAddressNode.kt | 4 +- .../EditRoomAddressPresenter.kt | 4 +- .../editroomaddress/EditRoomAddressState.kt | 2 +- .../EditRoomAddressStateProvider.kt | 2 +- .../editroomaddress/EditRoomAddressView.kt | 4 +- .../impl}/editroomaddress/RoomAlias.kt | 2 +- .../impl/root}/SecurityAndPrivacyEvents.kt | 2 +- .../impl/root}/SecurityAndPrivacyNode.kt | 3 +- .../impl/root}/SecurityAndPrivacyPresenter.kt | 7 +-- .../impl/root}/SecurityAndPrivacyState.kt | 4 +- .../root}/SecurityAndPrivacyStateProvider.kt | 4 +- .../impl/root}/SecurityAndPrivacyView.kt | 6 +-- .../src/main/res/values-be/translations.xml | 5 ++ .../src/main/res/values-bg/translations.xml | 23 +++++++++ .../src/main/res/values-cs/translations.xml | 38 +++++++++++++++ .../src/main/res/values-cy/translations.xml | 38 +++++++++++++++ .../src/main/res/values-da/translations.xml | 36 ++++++++++++++ .../src/main/res/values-de/translations.xml | 38 +++++++++++++++ .../src/main/res/values-el/translations.xml | 37 ++++++++++++++ .../src/main/res/values-es/translations.xml | 36 ++++++++++++++ .../src/main/res/values-et/translations.xml | 40 ++++++++++++++++ .../src/main/res/values-eu/translations.xml | 22 +++++++++ .../src/main/res/values-fa/translations.xml | 22 +++++++++ .../src/main/res/values-fi/translations.xml | 38 +++++++++++++++ .../src/main/res/values-fr/translations.xml | 38 +++++++++++++++ .../src/main/res/values-hu/translations.xml | 40 ++++++++++++++++ .../src/main/res/values-in/translations.xml | 35 ++++++++++++++ .../src/main/res/values-it/translations.xml | 37 ++++++++++++++ .../src/main/res/values-ko/translations.xml | 36 ++++++++++++++ .../src/main/res/values-nb/translations.xml | 36 ++++++++++++++ .../src/main/res/values-nl/translations.xml | 5 ++ .../src/main/res/values-pl/translations.xml | 38 +++++++++++++++ .../main/res/values-pt-rBR/translations.xml | 36 ++++++++++++++ .../src/main/res/values-pt/translations.xml | 38 +++++++++++++++ .../src/main/res/values-ro/translations.xml | 36 ++++++++++++++ .../src/main/res/values-ru/translations.xml | 40 ++++++++++++++++ .../src/main/res/values-sk/translations.xml | 38 +++++++++++++++ .../src/main/res/values-sv/translations.xml | 37 ++++++++++++++ .../src/main/res/values-tr/translations.xml | 38 +++++++++++++++ .../src/main/res/values-uk/translations.xml | 38 +++++++++++++++ .../src/main/res/values-uz/translations.xml | 7 +++ .../main/res/values-zh-rTW/translations.xml | 38 +++++++++++++++ .../src/main/res/values-zh/translations.xml | 38 +++++++++++++++ .../impl/src/main/res/values/localazy.xml | 40 ++++++++++++++++ .../impl}/FakeSecurityAndPrivacyNavigator.kt | 2 +- .../impl}/SecurityAndPrivacyPresenterTest.kt | 6 ++- .../impl}/SecurityAndPrivacyViewTest.kt | 10 +++- .../EditRoomAddressPresenterTest.kt} | 46 ++++++++++-------- .../EditRoomAddressViewTest.kt} | 4 +- .../securityandprivacy/test/build.gradle.kts | 22 +++++++++ .../test/FakeSecurityAndPrivacyEntryPoint.kt | 19 ++++++++ tools/localazy/config.json | 7 +++ 64 files changed, 1296 insertions(+), 55 deletions(-) create mode 100644 features/securityandprivacy/api/build.gradle.kts create mode 100644 features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyEntryPoint.kt rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/permissions => securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api}/SecurityAndPrivacyPermissions.kt (89%) create mode 100644 features/securityandprivacy/impl/build.gradle.kts create mode 100644 features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/DefaultSecurityAndPrivacyEntryPoint.kt rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl}/SecurityAndPrivacyFlowNode.kt (89%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl}/SecurityAndPrivacyNavigator.kt (92%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl}/editroomaddress/EditRoomAddressEvents.kt (83%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl}/editroomaddress/EditRoomAddressNode.kt (87%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl}/editroomaddress/EditRoomAddressPresenter.kt (97%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl}/editroomaddress/EditRoomAddressState.kt (88%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl}/editroomaddress/EditRoomAddressStateProvider.kt (94%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl}/editroomaddress/EditRoomAddressView.kt (96%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl}/editroomaddress/RoomAlias.kt (87%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root}/SecurityAndPrivacyEvents.kt (92%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root}/SecurityAndPrivacyNode.kt (89%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root}/SecurityAndPrivacyPresenter.kt (97%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root}/SecurityAndPrivacyState.kt (93%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root}/SecurityAndPrivacyStateProvider.kt (95%) rename features/{roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root}/SecurityAndPrivacyView.kt (98%) create mode 100644 features/securityandprivacy/impl/src/main/res/values-be/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-bg/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-cs/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-cy/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-da/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-de/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-el/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-es/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-et/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-eu/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-fa/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-fi/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-fr/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-hu/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-in/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-it/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-ko/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-nb/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-nl/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-pl/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-pt/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-ro/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-ru/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-sk/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-sv/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-tr/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-uk/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-uz/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-zh-rTW/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values-zh/translations.xml create mode 100644 features/securityandprivacy/impl/src/main/res/values/localazy.xml rename features/{roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl}/FakeSecurityAndPrivacyNavigator.kt (90%) rename features/{roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl}/SecurityAndPrivacyPresenterTest.kt (97%) rename features/{roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy => securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl}/SecurityAndPrivacyViewTest.kt (90%) rename features/{roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditBaseRoomAddressPresenterTest.kt => securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressPresenterTest.kt} (93%) rename features/{roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditBaseRoomAddressViewTest.kt => securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressViewTest.kt} (97%) create mode 100644 features/securityandprivacy/test/build.gradle.kts create mode 100644 features/securityandprivacy/test/src/main/kotlin/io/element/android/features/securityandprivacy/test/FakeSecurityAndPrivacyEntryPoint.kt diff --git a/features/roomdetails/impl/build.gradle.kts b/features/roomdetails/impl/build.gradle.kts index acf80c0eca..4ca260be16 100644 --- a/features/roomdetails/impl/build.gradle.kts +++ b/features/roomdetails/impl/build.gradle.kts @@ -58,6 +58,7 @@ dependencies { implementation(projects.features.reportroom.api) implementation(projects.features.roommembermoderation.api) implementation(projects.features.rolesandpermissions.api) + implementation(projects.features.securityandprivacy.api) implementation(projects.features.invitepeople.api) testCommonDependencies(libs, true) @@ -71,6 +72,7 @@ dependencies { testImplementation(projects.libraries.featureflag.test) testImplementation(projects.features.call.test) testImplementation(projects.features.rolesandpermissions.test) + testImplementation(projects.features.securityandprivacy.test) testImplementation(projects.features.knockrequests.test) testImplementation(projects.features.messages.test) testImplementation(projects.features.poll.test) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt index fe6c3646d9..c8ef60513c 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsFlowNode.kt @@ -40,7 +40,7 @@ import io.element.android.features.roomdetails.impl.invite.RoomInviteMembersNode import io.element.android.features.roomdetails.impl.members.RoomMemberListNode import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsNode import io.element.android.features.roomdetails.impl.notificationsettings.RoomNotificationSettingsNode -import io.element.android.features.roomdetails.impl.securityandprivacy.SecurityAndPrivacyFlowNode +import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint import io.element.android.features.userprofile.shared.UserProfileNodeHelper import io.element.android.features.verifysession.api.OutgoingVerificationEntryPoint import io.element.android.libraries.architecture.BackstackWithOverlayBox @@ -84,6 +84,7 @@ class RoomDetailsFlowNode( private val reportRoomEntryPoint: ReportRoomEntryPoint, private val changeRoomMemberRolesEntryPoint: ChangeRoomMemberRolesEntryPoint, private val rolesAndPermissionsEntryPoint: RolesAndPermissionsEntryPoint, + private val securityAndPrivacyEntryPoint: SecurityAndPrivacyEntryPoint, ) : BaseFlowNode( backstack = BackStack( initialElement = plugins.filterIsInstance().first().initialElement.toNavTarget(), @@ -381,7 +382,7 @@ class RoomDetailsFlowNode( knockRequestsListEntryPoint.createNode(this, buildContext) } NavTarget.SecurityAndPrivacy -> { - createNode(buildContext) + securityAndPrivacyEntryPoint.createNode(this, buildContext) } is NavTarget.VerifyUser -> { val params = OutgoingVerificationEntryPoint.Params( diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt index 232f4d626c..95c4f1e9e2 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt +++ b/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/RoomDetailsPresenter.kt @@ -22,7 +22,7 @@ import io.element.android.features.leaveroom.api.LeaveRoomEvent import io.element.android.features.leaveroom.api.LeaveRoomState import io.element.android.features.roomcall.api.RoomCallState import io.element.android.features.roomdetails.impl.members.details.RoomMemberDetailsPresenter -import io.element.android.features.roomdetails.impl.securityandprivacy.permissions.securityAndPrivacyPermissionsAsState +import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissionsAsState import io.element.android.libraries.androidutils.clipboard.ClipboardHelper import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.core.coroutine.CoroutineDispatchers diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/DefaultRoomDetailsEntryPointTest.kt b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/DefaultRoomDetailsEntryPointTest.kt index 2b336121da..cd2af112a7 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/DefaultRoomDetailsEntryPointTest.kt +++ b/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/DefaultRoomDetailsEntryPointTest.kt @@ -20,6 +20,7 @@ import io.element.android.features.messages.test.FakeMessagesEntryPoint import io.element.android.features.poll.test.history.FakePollHistoryEntryPoint import io.element.android.features.reportroom.test.FakeReportRoomEntryPoint import io.element.android.features.roomdetails.api.RoomDetailsEntryPoint +import io.element.android.features.securityandprivacy.test.FakeSecurityAndPrivacyEntryPoint import io.element.android.features.verifysession.test.FakeOutgoingVerificationEntryPoint import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId @@ -61,6 +62,7 @@ class DefaultRoomDetailsEntryPointTest { reportRoomEntryPoint = FakeReportRoomEntryPoint(), changeRoomMemberRolesEntryPoint = FakeChangeRoomMemberRolesEntryPoint(), rolesAndPermissionsEntryPoint = FakeRolesAndPermissionsEntryPoint(), + securityAndPrivacyEntryPoint = FakeSecurityAndPrivacyEntryPoint(), ) } val callback = object : RoomDetailsEntryPoint.Callback { diff --git a/features/securityandprivacy/api/build.gradle.kts b/features/securityandprivacy/api/build.gradle.kts new file mode 100644 index 0000000000..4260bea661 --- /dev/null +++ b/features/securityandprivacy/api/build.gradle.kts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +plugins { + id("io.element.android-compose-library") + id("kotlin-parcelize") +} + +android { + namespace = "io.element.android.features.securityandprivacy.api" +} +dependencies { + implementation(projects.libraries.architecture) + implementation(projects.libraries.core) + implementation(projects.libraries.matrix.api) +} diff --git a/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyEntryPoint.kt b/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyEntryPoint.kt new file mode 100644 index 0000000000..2c7c1cfd41 --- /dev/null +++ b/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyEntryPoint.kt @@ -0,0 +1,13 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.securityandprivacy.api + +import io.element.android.libraries.architecture.SimpleFeatureEntryPoint + +fun interface SecurityAndPrivacyEntryPoint : SimpleFeatureEntryPoint diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/permissions/SecurityAndPrivacyPermissions.kt b/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt similarity index 89% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/permissions/SecurityAndPrivacyPermissions.kt rename to features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt index e4b14c923a..82ab30581e 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/permissions/SecurityAndPrivacyPermissions.kt +++ b/features/securityandprivacy/api/src/main/kotlin/io/element/android/features/securityandprivacy/api/SecurityAndPrivacyPermissions.kt @@ -6,12 +6,12 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy.permissions +package io.element.android.features.securityandprivacy.api import androidx.compose.runtime.Composable import androidx.compose.runtime.State import androidx.compose.runtime.produceState -import io.element.android.features.roomdetails.impl.securityandprivacy.permissions.SecurityAndPrivacyPermissions.Companion.DEFAULT +import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions.Companion.DEFAULT import io.element.android.libraries.matrix.api.room.BaseRoom import io.element.android.libraries.matrix.api.room.StateEventType import io.element.android.libraries.matrix.api.room.powerlevels.canSendState diff --git a/features/securityandprivacy/impl/build.gradle.kts b/features/securityandprivacy/impl/build.gradle.kts new file mode 100644 index 0000000000..5a83cebd8c --- /dev/null +++ b/features/securityandprivacy/impl/build.gradle.kts @@ -0,0 +1,48 @@ +import extension.setupDependencyInjection +import extension.testCommonDependencies + +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +plugins { + id("io.element.android-compose-library") + id("kotlin-parcelize") +} + +android { + namespace = "io.element.android.features.securityandprivacy.impl" + + testOptions { + unitTests { + isIncludeAndroidResources = true + } + } +} + +setupDependencyInjection() + +dependencies { + api(projects.features.securityandprivacy.api) + implementation(projects.appnav) + implementation(projects.libraries.architecture) + implementation(projects.libraries.core) + implementation(projects.libraries.designsystem) + implementation(projects.libraries.matrix.api) + // For test fixtures used in previews + implementation(projects.libraries.previewutils) + implementation(projects.libraries.matrixui) + implementation(projects.libraries.uiStrings) + implementation(projects.services.analytics.api) + implementation(projects.libraries.featureflag.api) + + testCommonDependencies(libs, true) + testImplementation(projects.services.analytics.test) + testImplementation(projects.libraries.matrix.test) + testImplementation(projects.libraries.featureflag.test) + testImplementation(projects.libraries.testtags) +} diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/DefaultSecurityAndPrivacyEntryPoint.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/DefaultSecurityAndPrivacyEntryPoint.kt new file mode 100644 index 0000000000..2d01ed4a83 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/DefaultSecurityAndPrivacyEntryPoint.kt @@ -0,0 +1,23 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.securityandprivacy.impl + +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import dev.zacsweers.metro.ContributesBinding +import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint +import io.element.android.libraries.architecture.createNode +import io.element.android.libraries.di.RoomScope + +@ContributesBinding(RoomScope::class) +class DefaultSecurityAndPrivacyEntryPoint : SecurityAndPrivacyEntryPoint { + override fun createNode(parentNode: Node, buildContext: BuildContext): Node { + return parentNode.createNode(buildContext) + } +} diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyFlowNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt similarity index 89% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyFlowNode.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt index 751ef01403..5dbc8dbb45 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyFlowNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyFlowNode.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy +package io.element.android.features.securityandprivacy.impl import android.os.Parcelable import androidx.compose.runtime.Composable @@ -18,7 +18,8 @@ import com.bumble.appyx.navmodel.backstack.BackStack import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode -import io.element.android.features.roomdetails.impl.securityandprivacy.editroomaddress.EditRoomAddressNode +import io.element.android.features.securityandprivacy.impl.editroomaddress.EditRoomAddressNode +import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyNode import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.createNode diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyNavigator.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt similarity index 92% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyNavigator.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt index 5a3857ee5b..3b71868bbf 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyNavigator.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyNavigator.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy +package io.element.android.features.securityandprivacy.impl import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.navmodel.backstack.BackStack diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressEvents.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressEvents.kt similarity index 83% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressEvents.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressEvents.kt index a21eaa1db3..e42236d31c 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressEvents.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressEvents.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy.editroomaddress +package io.element.android.features.securityandprivacy.impl.editroomaddress sealed interface EditRoomAddressEvents { data object Save : EditRoomAddressEvents diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressNode.kt similarity index 87% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressNode.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressNode.kt index 415654aa35..ba92cfb6d0 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressNode.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy.editroomaddress +package io.element.android.features.securityandprivacy.impl.editroomaddress import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -17,7 +17,7 @@ import com.bumble.appyx.core.plugin.plugins import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode -import io.element.android.features.roomdetails.impl.securityandprivacy.SecurityAndPrivacyNavigator +import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator import io.element.android.libraries.di.RoomScope @ContributesNode(RoomScope::class) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressPresenter.kt similarity index 97% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressPresenter.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressPresenter.kt index 79f9d21b13..8dcea0d880 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressPresenter.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy.editroomaddress +package io.element.android.features.securityandprivacy.impl.editroomaddress import androidx.compose.runtime.Composable import androidx.compose.runtime.MutableState @@ -20,7 +20,7 @@ import androidx.compose.runtime.setValue import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedFactory import dev.zacsweers.metro.AssistedInject -import io.element.android.features.roomdetails.impl.securityandprivacy.SecurityAndPrivacyNavigator +import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runCatchingUpdatingState diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressState.kt similarity index 88% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressState.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressState.kt index 3aabf06f0c..89315ab8ce 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressState.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy.editroomaddress +package io.element.android.features.securityandprivacy.impl.editroomaddress import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.ui.room.address.RoomAddressValidity diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressStateProvider.kt similarity index 94% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressStateProvider.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressStateProvider.kt index 22b0021416..7b82175bb7 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressStateProvider.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy.editroomaddress +package io.element.android.features.securityandprivacy.impl.editroomaddress import androidx.compose.ui.tooling.preview.PreviewParameterProvider import io.element.android.libraries.architecture.AsyncAction diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressView.kt similarity index 96% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressView.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressView.kt index 5a893c60da..da18b963fa 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditRoomAddressView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressView.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy.editroomaddress +package io.element.android.features.securityandprivacy.impl.editroomaddress import androidx.compose.foundation.layout.Box import androidx.compose.foundation.layout.consumeWindowInsets @@ -21,7 +21,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.res.stringResource import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp -import io.element.android.features.roomdetails.impl.R +import io.element.android.features.securityandprivacy.impl.R import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults import io.element.android.libraries.designsystem.components.button.BackButton diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/RoomAlias.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/RoomAlias.kt similarity index 87% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/RoomAlias.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/RoomAlias.kt index 0624939177..f9ae4bf958 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/RoomAlias.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/RoomAlias.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy.editroomaddress +package io.element.android.features.securityandprivacy.impl.editroomaddress import io.element.android.libraries.matrix.api.core.RoomAlias diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyEvents.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvents.kt similarity index 92% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyEvents.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvents.kt index f5afb0c335..8119ddb0c4 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyEvents.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvents.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy +package io.element.android.features.securityandprivacy.impl.root sealed interface SecurityAndPrivacyEvents { data object EditRoomAddress : SecurityAndPrivacyEvents diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt similarity index 89% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyNode.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt index 219e4b092f..87ba27cb02 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy +package io.element.android.features.securityandprivacy.impl.root import androidx.compose.runtime.Composable import androidx.compose.ui.Modifier @@ -17,6 +17,7 @@ import com.bumble.appyx.core.plugin.plugins import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode +import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator import io.element.android.libraries.di.RoomScope @ContributesNode(RoomScope::class) diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt similarity index 97% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyPresenter.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index ae093c6bc8..7c0c04f8c3 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy +package io.element.android.features.securityandprivacy.impl.root import androidx.compose.runtime.Composable import androidx.compose.runtime.LaunchedEffect @@ -21,8 +21,9 @@ import androidx.compose.runtime.setValue import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedFactory import dev.zacsweers.metro.AssistedInject -import io.element.android.features.roomdetails.impl.securityandprivacy.editroomaddress.matchesServer -import io.element.android.features.roomdetails.impl.securityandprivacy.permissions.securityAndPrivacyPermissionsAsState +import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator +import io.element.android.features.securityandprivacy.impl.editroomaddress.matchesServer +import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissionsAsState import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.Presenter diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt similarity index 93% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyState.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index cfba61341e..be9c24dc65 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -6,9 +6,9 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy +package io.element.android.features.securityandprivacy.impl.root -import io.element.android.features.roomdetails.impl.securityandprivacy.permissions.SecurityAndPrivacyPermissions +import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import kotlinx.collections.immutable.toImmutableSet diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt similarity index 95% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyStateProvider.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt index 135d6c48d6..c13fc36d34 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt @@ -6,10 +6,10 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy +package io.element.android.features.securityandprivacy.impl.root import androidx.compose.ui.tooling.preview.PreviewParameterProvider -import io.element.android.features.roomdetails.impl.securityandprivacy.permissions.SecurityAndPrivacyPermissions +import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyPermissions import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData diff --git a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt similarity index 98% rename from features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyView.kt rename to features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index b32654ccb1..7eeabba3c0 100644 --- a/features/roomdetails/impl/src/main/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy +package io.element.android.features.securityandprivacy.impl.root import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column @@ -30,7 +30,7 @@ import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons -import io.element.android.features.roomdetails.impl.R +import io.element.android.features.securityandprivacy.impl.R import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.coverage.ExcludeFromCoverage import io.element.android.libraries.designsystem.components.async.AsyncActionView @@ -143,7 +143,7 @@ private fun SecurityAndPrivacyToolbar( ) { TopAppBar( modifier = modifier, - titleStr = stringResource(R.string.screen_room_details_security_and_privacy_title), + titleStr = stringResource(R.string.screen_security_and_privacy_title), navigationIcon = { BackButton(onClick = onBackClick) }, actions = { TextButton( diff --git a/features/securityandprivacy/impl/src/main/res/values-be/translations.xml b/features/securityandprivacy/impl/src/main/res/values-be/translations.xml new file mode 100644 index 0000000000..166afb9568 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-be/translations.xml @@ -0,0 +1,5 @@ + + + "Папрасіце далучыцца" + "Хто заўгодна" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-bg/translations.xml b/features/securityandprivacy/impl/src/main/res/values-bg/translations.xml new file mode 100644 index 0000000000..7ae4ba25cf --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-bg/translations.xml @@ -0,0 +1,23 @@ + + + "Добавяне на адрес на стаята" + "Да, включване на шифроването" + "Да се включи ли шифроването?" + "Веднъж включено, шифроването не може да бъде изключено." + "Включване на шифроване от край до край" + "Всеки може да намери и да се присъедини" + "Хората могат да се присъединят само ако са поканени" + "Само с покана" + "Достъп до стаята" + "Пространствата в момента не се поддържат" + "Членове на пространството" + "Ще ви е необходим адрес на стаята, за да я направите видима в директорията на стаите." + "Видима в директорията на обществените стаи" + "Кой може да чете историята" + "Само за членове откакто са поканени" + "Само за членове от избирането на тази опция" + "Защита и поверителност" + "Шифроване" + "Всеки" + "Видимост на стаята" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-cs/translations.xml b/features/securityandprivacy/impl/src/main/res/values-cs/translations.xml new file mode 100644 index 0000000000..299ac2b643 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-cs/translations.xml @@ -0,0 +1,38 @@ + + + "Aby byla místnost v adresáři viditelná, je třeba zadat její adresu." + "Adresa místnosti" + "Přidat adresu místnosti" + "Kdokoli může požádat o vstup do místnosti, ale správce nebo moderátor bude muset žádost přijmout." + "Ano, povolit šifrování" + "Po aktivaci nelze šifrování místnosti deaktivovat. Historie zpráv bude viditelná pouze pro členy místnosti od doby, kdy byli pozváni nebo od té doby, co do místnosti vstoupili. +Nikdo kromě členů místnosti nebude moci číst zprávy. To může bránit správnému fungování robotů a propojení. +Nedoporučujeme povolovat šifrování pro místnosti, které může kdokoli najít a vstoupit do nich." + "Povolit šifrování?" + "Jakmile je povoleno, šifrování nelze zakázat." + "Povolit koncové šifrování" + "Každý může najít a vstoupit" + "Kdokoliv" + "Lidé mohou vstoupit, pouze pokud jsou pozváni" + "Pouze pro zvané" + "Přístup do místnosti" + "Prostory nejsou aktuálně podporovány" + "Členové prostoru" + "Budete potřebovat adresu místnosti, aby byla viditelná v adresáři místností." + "Adresa místnosti" + "Umožněte nalezení této místnosti prohledáním adresáře veřejných místností na %1$s" + "Viditelné v adresáři veřejných místností" + "Kdo může číst historii" + "Pouze členové od té doby, co byli pozváni" + "Pouze členové od výběru této možnosti" + "Adresy místností představují způsoby, jak najít místnosti a získat k nim přístup. Díky tomu můžete svoji místnost snadno sdílet s ostatními. +Můžete se rozhodnout publikovat svou místnost ve veřejném adresáři místnosti vašeho domovského serveru." + "Publikování místnosti" + "Adresy místností představují způsoby, jak najít místnosti a získat k nim přístup. Díky tomu můžete svoji místnost snadno sdílet s ostatními. +Adresa je také vyžadována pro zobrazení místnosti v adresáři veřejných místností %1$s." + "Zabezpečení a soukromí" + "Požádat o připojení" + "Šifrování" + "Kdokoliv" + "Viditelnost místnosti" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-cy/translations.xml b/features/securityandprivacy/impl/src/main/res/values-cy/translations.xml new file mode 100644 index 0000000000..249fa6a1da --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-cy/translations.xml @@ -0,0 +1,38 @@ + + + "Bydd angen cyfeiriad ystafell arnoch i\'w wneud yn weladwy yn y cyfeiriadur." + "Cyfeiriad yr ystafell" + "Ychwanegu cyfeiriad ystafell" + "Gall unrhyw un ofyn am gael ymuno â\'r ystafell ond bydd rhaid i weinyddwr neu gymedrolwr dderbyn y cais." + "Iawn, galluogi amgryptio" + "Unwaith y bydd wedi\'i alluogi, does dim modd analluogi amgryptio ar gyfer ystafell, dim ond ar gyfer aelodau\'r ystafell y bydd hanes neges yn weladwy ers iddyn nhw gael eu gwahodd neu ers iddyn nhw ymuno â\'r ystafell. +Fydd neb ar wahân i aelodau\'r ystafell yn gallu darllen negeseuon. Gall hyn atal botiau a phontydd i weithio\'n gywir. +Nid ydym yn argymell galluogi amgryptio ar gyfer ystafelloedd y gall unrhyw un ddod o hyd iddynt ac ymuno â nhw." + "Galluogi amgryptio?" + "Unwaith y bydd wedi\'i alluogi, does dim modd analluogi amgryptio." + "Galluogi amgryptio o\'r dechrau i\'r diwedd" + "Gall unrhyw un ddod o hyd iddo ac ymuno" + "Unrhyw un" + "Dim ond os cawn nhw wahoddiad gall pobl ymuno" + "Gwahoddiad yn unig" + "Mynediad ystafell" + "Nid yw gofodau\'n cael eu cefnogi ar hyn o bryd" + "Aelodau gofod" + "Bydd angen cyfeiriad ystafell arnoch er mwyn ei wneud yn weladwy yn y cyfeiriadur ystafelloedd." + "Cyfeiriad yr ystafell" + "Caniatáu i\'r ystafell hon gael ei chanfod trwy chwilio cyfeiriadur ystafelloedd cyhoeddus %1$s" + "Gweladwy yn y cyfeiriadur ystafelloedd cyhoeddus" + "Pwy all ddarllen hanes" + "Yn aelodau ond dim ond ers cael eu gwahodd" + "Yn aelodau dim ond ers dewis y dewis hwn" + "Mae cyfeiriadau ystafelloedd yn ffyrdd o ddod o hyd i ystafelloedd a chael mynediad iddyn nhw. Mae hyn hefyd yn sicrhau y gallwch chi rannu\'ch ystafell yn hawdd ag eraill. +Gallwch ddewis cyhoeddi eich ystafell yng ngweinydd cartref eich cyfeiriadur ystafelloedd cyhoeddus." + "Cyhoeddi ystafell" + "Mae cyfeiriadau ystafelloedd yn ffyrdd o ddod o hyd i ystafelloedd a chael mynediad iddyn nhw. Mae hyn hefyd yn sicrhau y gallwch chi rannu\'ch ystafell yn hawdd ag eraill. +Mae angen y cyfeiriad hefyd i wneud yr ystafell yn weladwy yng nghyfeiriadur ystafell gyhoeddus %1$s." + "Diogelwch a phreifatrwydd" + "Gofyn i gael ymuno" + "Amgryptiad" + "Unrhyw un" + "Gwelededd yr ystafell" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-da/translations.xml b/features/securityandprivacy/impl/src/main/res/values-da/translations.xml new file mode 100644 index 0000000000..1a8a9046b6 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-da/translations.xml @@ -0,0 +1,36 @@ + + + "Du skal bruge en rum-adresse for at gøre den synlig i kataloget." + "Rummets adresse" + "Tilføj adresse på rum" + "Alle kan bede om at deltage i lokalet, men en administrator eller moderator skal acceptere anmodningen." + "Ja, aktivér kryptering" + "Når det først er aktiveret, kan kryptering for et rum ikke deaktiveres igen. Beskedhistorik vil kun være synlig for rummedlemmer, siden de blev inviteret, eller siden de blev medlem af rummet. +Ingen udover medlemmer af rummet vil være i stand til at læse beskeder. Dette kan forhindre bots og broer i at fungere korrekt. +Vi anbefaler ikke at aktivere kryptering for rum, som alle kan finde og deltage i." + "Aktivér kryptering?" + "Når kryptering først er aktiveret, kan den ikke deaktiveres igen." + "Aktivér end-to-end-kryptering" + "Alle kan finde og deltage" + "Andre kan kun deltage, hvis de bliver inviteret" + "Kun med invitation" + "Adgang til rummet" + "Grupper understøttes ikke i øjeblikket" + "Medlemmer af gruppen" + "Du skal bruge en adresse til rummet, for at gøre den synlig i rum-registeret." + "Tillad, at dette rum kan findes ved at søge i %1$s fortegnelse over offentlige rum" + "Synlig i det offentlige register over rum" + "Hvem kan læse historikken?" + "Kun medlemmer, efter de blev inviteret" + "Kun medlemmer siden valg af denne mulighed" + "Rum-adresser er en måde at finde og få adgang til værelser på. Dette sikrer også, at du nemt kan dele dit rum med andre. +Du kan vælge at offentliggøre dit rum i din hjemmeservers offentlige katalog over rum." + "Udgivelse af rum" + "Rum-adresser er måder at finde og få adgang til rum på. Dette sikrer også, at du nemt kan dele dit rum med andre. +Adressen er også påkrævet for at gøre rummet synligt i det %1$s offentlige register." + "Sikkerhed og privatliv" + "Spørg om at deltage" + "Kryptering" + "Enhver" + "Rummets synlighed" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-de/translations.xml b/features/securityandprivacy/impl/src/main/res/values-de/translations.xml new file mode 100644 index 0000000000..cc311a70f4 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-de/translations.xml @@ -0,0 +1,38 @@ + + + "Du benötigst eine Chat-Adresse, um den Chat im Verzeichnis sichtbar zu machen." + "Chat-Adresse" + "Chat-Adresse hinzufügen" + "Jeder kann den Beitritt zum Chat anfragen, aber ein Admin oder Moderator müssen die Anfrage akzeptieren." + "Ja, Verschlüsselung aktivieren" + "Einmal angeschaltet kann die Verschlüsselung für einen Chat nicht mehr deaktiviert werden. Der Nachrichtenverlauf ist für Mitglieder nur sichtbar, seit sie eingeladen wurden oder dem Chat beigetreten sind. +Niemand außer den Chat Mitgliedern kann Nachrichten lesen. Dies kann verhindern, dass Bots und Bridges richtig funktionieren. +Wir empfehlen keine Verschlüsselung für Chats zu aktivieren, die jeder finden und denen jeder beitreten darf." + "Verschlüsselung aktivieren?" + "Einmal angeschaltet kann die Verschlüsselung nicht mehr deaktiviert werden." + "Ende-zu-Ende-Verschlüsselung aktivieren" + "Jeder kann diesen Chat finden und ihm beitreten" + "Alle" + "Personen können nur beitreten, wenn sie eingeladen werden." + "Nur auf Einladung" + "Chat Zugang" + "Spaces werden zur Zeit nicht unterstützt." + "Spacemitglieder" + "Du benötigst eine Chat-Adresse, um den Chat im Verzeichnis sichtbar zu machen." + "Chatroomadresse" + "Erlaube das Auffinden dieses Chats durch Suche im öffentlichen Verzeichnis von %1$s" + "Sichtbar im öffentlichen Verzeichnis" + "Wer hat Zugriff auf den Nachrichtenverlauf" + "Nur Mitglieder, aber erst seit deren Einladung" + "Nur Mitglieder seit Auswahl dieser Option" + "Chat-Adressen machen es möglich, Chats zu finden und ihnen beizutreten. Dies erleichtert es, Chats mit anderen zu teilen. +Auf Wunsch kannst du deinen Chat im öffentlichen Verzeichnis deines Homeservers veröffentlichen." + "Veröffentlichung von Chats" + "Chat-Adressen machen es möglich, Chats zu finden und ihnen beizutreten. Dies erleichtert es, Chats mit anderen zu teilen. +Die Adresse ist auch erforderlich, um den Chat im öffentlichen Verzeichnis von %1$s zu veröffentlichen." + "Sicherheit & Datenschutz" + "Beitritt beantragen" + "Verschlüsselung" + "Jeder" + " Sichtbarkeit des Chats" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-el/translations.xml b/features/securityandprivacy/impl/src/main/res/values-el/translations.xml new file mode 100644 index 0000000000..8e2f0ad361 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-el/translations.xml @@ -0,0 +1,37 @@ + + + "Θα χρειαστείτε μια διεύθυνση αίθουσας για να την κάνετε ορατή στον κατάλογο." + "Διεύθυνση αίθουσας" + "Προσθήκη διεύθυνσης αίθουσας" + "Οποιοσδήποτε μπορεί να ζητήσει να συμμετάσχει στην αίθουσα, αλλά ένας διαχειριστής ή συντονιστής θα πρέπει να αποδεχτεί το αίτημα." + "Ναι, ενεργοποιήστε την κρυπτογράφηση" + "Μόλις ενεργοποιηθεί, η κρυπτογράφηση για μια αίθουσα δεν μπορεί να απενεργοποιηθεί, το ιστορικό μηνυμάτων θα είναι ορατό μόνο για τα μέλη της αίθουσας από τότε που προσκλήθηκαν ή από τότε που συμμετείχαν στην αίθουσα. +Κανείς άλλος εκτός από τα μέλη της αίθουσας δεν θα μπορεί να διαβάσει τα μηνύματα. Αυτό μπορεί να εμποδίσει τη σωστή λειτουργία των bots και των γεφυρών. +Δεν συνιστούμε την ενεργοποίηση της κρυπτογράφησης για αίθουσες που μπορεί να βρει και να συμμετάσχει ο καθένας." + "Ενεργοποίηση κρυπτογράφησης;" + "Μόλις ενεργοποιηθεί, η κρυπτογράφηση δεν μπορεί να απενεργοποιηθεί." + "Ενεργοποίηση κρυπτογράφησης από άκρο σε άκρο" + "Οποιοσδήποτε μπορεί να βρει και να συμμετάσχει" + "Οποιοσδήποτε" + "Τα άτομα μπορούν να συμμετάσχουν μόνο εάν έχουν προσκληθεί" + "Μόνο πρόσκληση" + "Πρόσβαση στην αίθουσα" + "Οι χώροι δεν υποστηρίζονται προς το παρόν" + "Μέλη χώρου" + "Θα χρειαστείτε μια διεύθυνση αίθουσας για να την κάνετε ορατή στον κατάλογο αιθουσών." + "Επιστρέψτε την εύρεση αυτής της αίθουσας με αναζήτηση στον κατάλογο %1$s δημοσίων αιθουσών" + "Ορατή στον κατάλογο δημόσιων αιθουσών" + "Ποιος μπορεί να διαβάσει το ιστορικό" + "Μόνο μέλη από τη στιγμή που προσκλήθηκαν" + "Μόνο για μέλη μετά από αυτήν την επιλογή" + "Οι διευθύνσεις αιθουσών είναι τρόποι εύρεσης και πρόσβασης σε αίθουσες. Αυτό διασφαλίζει επίσης ότι μπορείτε εύκολα να μοιραστείτε την αίθουσα με άλλους. +Μπορείτε να επιλέξετε να δημοσιεύσετε την αίθουσά σας στον δημόσιο κατάλογο αιθουσών του αρχικού διακομιστή σας." + "Δημοσίευση αίθουσας" + "Οι διευθύνσεις αιθουσών είναι τρόποι εύρεσης και πρόσβασης σε αίθουσες. Αυτό εξασφαλίζει επίσης ότι μπορείτε εύκολα να μοιραστείτε την αίθουσα με άλλους. +Η διεύθυνση απαιτείται επίσης για να γίνει η αίθουσα ορατή στον δημόσιο κατάλογο αιθουσών %1$s." + "Ασφάλεια & απόρρητο" + "Αίτημα συμμετοχής" + "Κρυπτογράφηση" + "Οποιοσδήποτε" + "Ορατότητα αίθουσας" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-es/translations.xml b/features/securityandprivacy/impl/src/main/res/values-es/translations.xml new file mode 100644 index 0000000000..912ab9db68 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-es/translations.xml @@ -0,0 +1,36 @@ + + + "Necesitarás una dirección de sala para que sea visible en el directorio." + "Dirección de la sala" + "Agregar dirección de sala" + "Cualquiera puede solicitar unirse a la sala, pero un administrador o moderador tendrá que aceptar la solicitud." + "Sí, activar cifrado" + "Una vez activado, el cifrado de una sala no se puede desactivar. El historial de mensajes solo será visible para los miembros de la sala desde que fueron invitados o desde que se unieron a la sala. +Nadie más que los miembros de la sala podrán leer los mensajes. Esto puede impedir que los bots y los puentes funcionen correctamente. +No recomendamos habilitar el cifrado para las salas que cualquiera pueda encontrar y unirse." + "¿Activar cifrado?" + "Una vez activado, el cifrado no se puede desactivar." + "Activar el cifrado de extremo a extremo" + "Cualquiera puede encontrarla y unirse" + "Las personas solo pueden unirse si están invitadas" + "Solo por invitación" + "Acceso a la sala" + "No se admiten los espacios por el momento." + "Miembros del espacio" + "Necesitarás una dirección de sala para que esta sea visible en el directorio de salas." + "Permite encontrar esta sala buscando en el directorio de salas públicas de %1$s" + "Visible en el directorio de salas públicas" + "Quién puede leer el historial" + "Solo participantes desde que fueron invitados" + "Solo participantes desde que se selecciona esta opción" + "Las direcciones de sala son formas de buscar salas y acceder a ellas. Esto también garantiza que puedas compartir fácilmente tu sala con otras personas. +Puedes optar por publicar tu sala en el directorio de salas públicas de tu servidor base." + "Publicación de la sala" + "Las direcciones de sala son un medio para buscar y acceder a salas. También te permiten compartir fácilmente tu sala con otras personas. +La dirección también es necesaria para hacer visible la sala en el directorio de salas públicas de %1$s." + "Seguridad y privacidad" + "Solicitud para unirse" + "Cifrado" + "Cualquiera" + "Visibilidad de la sala" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-et/translations.xml b/features/securityandprivacy/impl/src/main/res/values-et/translations.xml new file mode 100644 index 0000000000..77dd390f52 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-et/translations.xml @@ -0,0 +1,40 @@ + + + "Selleks, et jututuba oleks nähtav jututubade avalikus kataloogis, vajab ta aadressi." + "Muuda aadressi" + "Lisa jututoa aadress" + "Kõik võivad paluda jututoaga liitumist, kuid peakasutaja peab sellega nõustuma." + "Jah, lülita krüptimine sisse" + "Kui jututoa krüptimine on kord sisse lülitatud, siis seda välja lülitada ei saa. Sõnumite ajalugu on nähtav vaid jututoa liikmetele alates kutse saamise või liitumise hetkest. +Keegi teine peale jututoa liikmete ei saa sõnumeid lugeda. See võib takistada suhtlusrobotite ja/või võrgusildade toimimist. +Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega kõik võivad liituda." + "Kas võtame krüptimise kasutusele?" + "Kui krüptimine on kasutusel, siis seda enam väljalülitada ei saa." + "Võta läbiv krüptimine kasutusele" + "Kõik võivad jututoaga liituda" + "Avalik" + "Liituda saab vaid kutse olemasolul" + "Privaatne" + "Ligipääs" + "Kogukondade tugi veel puudub" + "Kogukonna liikmed" + "Et jututuba oleks nähtav avalikus kataloogis, peab tal olema aadress." + "Selleks, et jututuba oleks nähtav jututubade kataloogis, vajab ta aadressi." + "Avaldatud aadress" + "Võimalda leida seda jututuba avalikust kataloogist otsides „%1$s“" + "Luba leitavus avaliku kataloogi otsingust." + "Nähtav avalikus kataloogis" + "Kes võivad lugeda jututoa ajalugu" + "Liikmed peale kutse saamist" + "Liikmed peale selle valiku sisselülitamist" + "Jututoa aadressid annavad võimaluse neid leida ning saada neile ligi. Samuti võimaldab see jututuba teistele huvilistele jagada. +Lisaks võid sa jututoa avaldada oma koduserveri avalikus jututubade kataloogis." + "Jututoa avaldamine" + "Jututoa aadressid annavad võimaluse neid leida ning saada neile ligi. Samuti võimaldab see jututuba teistele huvilistele jagada. +Lisaks on aadress vajalik, et jututuba oleks %1$s serveri avalikus jututubade kataloogis nähtav." + "Turvalisus ja privaatsus" + "Küsi võimalust liitumiseks" + "Krüptimine" + "Kõik" + "Jututoa nähtavus" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-eu/translations.xml b/features/securityandprivacy/impl/src/main/res/values-eu/translations.xml new file mode 100644 index 0000000000..d7758c1f81 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-eu/translations.xml @@ -0,0 +1,22 @@ + + + "Gelaren helbidea" + "Gehitu gelaren helbidea" + "Bai, gaitu zifratzea" + "Edonork aurkitu eta bat egin dezake" + "Gonbidatutako pertsonak bakarrik sartu ahal izango dira" + "Gonbidapen bidez" + "Gelarako sarbidea" + "Gaur-gaurkoz ez da guneekin bateragarria" + "Guneko kideak" + "Gelarako helbideren bat beharko duzu gelen direktorioan ikusgai egon dadila nahi baduzu." + "Gelaren helbidea" + "Gela publikoen direktorioan ikusgai" + "Nork irakur dezake historia" + "Kideek bakarrik, gonbidatu zituztenetik" + "Kideek bakarrik, aukera hau hautatu zenetik" + "Segurtasuna eta pribatutasuna" + "Zifratzea" + "Edonork" + "Gelaren ikusgarritasuna" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-fa/translations.xml b/features/securityandprivacy/impl/src/main/res/values-fa/translations.xml new file mode 100644 index 0000000000..d3e96712de --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-fa/translations.xml @@ -0,0 +1,22 @@ + + + "نشانی اتاق" + "افزودن نشانی اتاق" + "بله. به کار انداختن رمزنگاری" + "رمزگذاری فعال شود؟" + "پس از به کار افتادن، رمزنگاری قابل از کار انداختن نیست." + "هرکسی می‌تواند یافته و بپیوندد" + "هرکسی" + "افراد فقط در صورت دعوت می‌توانند بپیوندند" + "فقط دعوتی" + "دسترسی اتاق" + "در حال حاضر فضاها پشتیبانی نمی‌شوند" + "اعضای فضا" + "نشانی اتاق" + "انتشار اتاق" + "امنیت و محرمانگی" + "درخواست دعوت" + "رمزنگاری" + "هرکسی" + "نمایانی اتاق" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-fi/translations.xml b/features/securityandprivacy/impl/src/main/res/values-fi/translations.xml new file mode 100644 index 0000000000..87440b626a --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-fi/translations.xml @@ -0,0 +1,38 @@ + + + "Tarvitset huoneen osoitteen, jotta se näkyy hakemistossa." + "Huoneen osoite" + "Lisää huoneen osoite" + "Kuka tahansa voi pyytää saada liittyä huoneeseen, mutta ylläpitäjän tai valvojan on hyväksyttävä pyyntö." + "Kyllä, ota salaus käyttöön" + "Kun salaus on kerran otettu käyttöön, sitä ei voi poistaa käytöstä. Viestihistoria näkyy vain huoneen jäsenille kutsusta tai liittymisestä lähtien. +Kukaan muu kuin huoneen jäsenet eivät pysty lukemaan viestejä. Tämä voi estää botteja tai siltoja toimimasta oikein. +Emme suosittele salauksen ottamista käyttöön huoneissa, jotka kuka tahansa voi löytää ja joihin kuka tahansa voi liittyä." + "Otetaanko salaus käyttöön?" + "Kun salaus on kerran otettu käyttöön, sitä ei voi poistaa käytöstä." + "Ota päästä päähän -salaus käyttöön" + "Kuka tahansa voi löytää ja liittyä." + "Kuka tahansa" + "Vain kutsutut henkilöt voivat liittyä" + "Vain kutsutut" + "Huoneeseen pääsy" + "Tiloja ei tällä hetkellä tueta" + "Tilan jäsenet" + "Tarvitset huoneen osoitteen, jotta se näkyy huonehakemistossa." + "Huoneen osoite" + "Salli tämän huoneen löytäminen hakemalla %1$s -palvelimen julkisesta huonehakemistosta." + "Näkyy julkisessa huonehakemistossa" + "Kuka voi lukea viestihistoriaa" + "Jäsenet vasta kutsusta lähtien" + "Jäsenet tämän vaihtoehdon valinnan jälkeen" + "Huoneosoitteet ovat tapoja löytää ja käyttää huoneita. Näin voit myös helposti jakaa huoneesi muiden kanssa. +Voit halutessasi julkaista huoneesi kotipalvelimesi julkisessa huonehakemistossa." + "Huoneen julkaiseminen" + "Huoneosoitteet ovat tapoja löytää ja käyttää huoneita. Näin voit myös helposti jakaa huoneesi muiden kanssa. +Osoitetta tarvitaan myös, jotta huone näkyy %1$s -palvelimen julkisessa huonehakemistossa." + "Turvallisuus ja yksityisyys" + "Pyydä liittymistä" + "Salaus" + "Kuka tahansa" + "Huoneen näkyvyys" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml b/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml new file mode 100644 index 0000000000..7a4be5d37a --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml @@ -0,0 +1,38 @@ + + + "Vous aurez besoin d\'une adresse de salon pour le rendre visible dans le répertoire." + "Adresse du salon" + "Ajouter l\'adresse du salon" + "N\'importe qui peut demander à rejoindre le salon, mais un administrateur ou un modérateur devra accepter la demande." + "Oui, activer le chiffrement" + "Une fois activé, le chiffrement d\'un salon ne peut pas être désactivé. L\'historique des messages ne sera visible que pour les membres depuis qu\'ils ont été invités ou depuis qu\'ils ont rejoint le salon. +Personne d\'autre que les membres du salon ne pourra lire les messages. Cela peut empêcher les bots et les bridges de fonctionner correctement. +Nous ne recommandons pas d\'activer le chiffrement pour les salons que tout le monde peut trouver et rejoindre." + "Activer le chiffrement ?" + "Une fois activé, le chiffrement ne peut pas être désactivé." + "Activer le chiffrement de bout en bout" + "Tout le monde peut le trouver et le rejoindre" + "Tout le monde" + "Le salon ne peut être joint que par les personnes invitées" + "Sur invitation uniquement" + "Accès au salon" + "Les Espaces ne sont pas encore supportés" + "Membres de l\'espace" + "Vous aurez besoin de l\'adresse du salon pour le rendre visible dans le répertoire des salons." + "Adresse du salon" + "Autoriser le salon à apparaître dans les résultats de recherche dans le répertoire %1$s des salons publics" + "Visible dans le répertoire des salons publics" + "Qui peux lire l\'historique" + "Les membres uniquement depuis qu\'ils ont été invités" + "Les membres uniquement depuis la sélection de cette option" + "Les adresses de salon sont un moyen de trouver et d\'accéder aux salons. Cela vous permet également de partager facilement votre salon avec d\'autres personnes. +Vous pouvez choisir de publier votre salon dans l\'annuaire des salons publics de votre serveur d’accueil." + "Publication du salon" + "Les adresses de salon sont un moyen de trouver et d\'accéder aux salons. Cela vous permet également de partager facilement votre salon avec d\'autres personnes. +L\'adresse est également requise pour que le salon soit visible dans le répertoire %1$s des salons publics." + "Sécurité & confidentialité" + "Demander à rejoindre" + "Chiffrement" + "Tout le monde" + "Visibilité du salon" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-hu/translations.xml b/features/securityandprivacy/impl/src/main/res/values-hu/translations.xml new file mode 100644 index 0000000000..b32923dba6 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-hu/translations.xml @@ -0,0 +1,40 @@ + + + "Szüksége lesz egy szobacímre, hogy láthatóvá tegye a szobakatalógusban." + "Cím szerkesztése" + "Szobacím hozzáadása" + "Bárki kérhet hozzáférést, de a kérést egy adminisztrátornak kell jóváhagynia." + "Igen, engedélyezze a titkosítást" + "Az engedélyezés után a szoba titkosítása nem tiltható le. Az üzenetek előzményei csak a szobatagok számára láthatók, amikor meghívást kaptak, vagy mióta csatlakoztak a szobához. +A szobatagokon kívül senki sem tudja olvasni az üzeneteket. Ez megakadályozhatja a botok és a hidak megfelelő működését. +Nem javasoljuk a titkosítás engedélyezését az olyan szobákban, amelyeket bárki megtalálhat és csatlakozhat." + "Engedélyezi a titkosítást?" + "Engedélyezés után a titkosítás nem tiltható le." + "Végpontok közötti titkosítás engedélyezése" + "Bárki csatlakozhat." + "Nyilvános" + "Csak a meghívott emberek léphetnek be." + "Privát" + "Hozzáférés" + "A terek jelenleg nem támogatottak" + "A tér tagjai" + "Szüksége lesz egy szobacímre, hogy láthatóvá tegye a szobakatalógusban." + "Szüksége lesz egy szobacímre, hogy láthatóvá váljon a szobakatalógusban." + "Közzétett cím" + "A szoba megtalálhatóvá tétele a(z) %1$s nyilvános szobakatalógusában való kereséssel." + "Lehetővé teszi, hogy a nyilvános szobakatalógusban megtalálható legyen." + "Látható a nyilvános szobakatalógusban" + "Ki olvashatja az előzményeket" + "Csak a tagok, a meghívásuktól kezdődően" + "Csak a tagok, a beállítás választásától kezdődően" + "A szobacímek a szobák megtalálásának és elérésnek módjai. Ez azt is biztosítja, hogy könnyen megoszthatja a szobáját másokkal. +Kiválaszthatja, hogy szobáját közzéteszi-e a Matrix-kiszolgáló nyilvános szobakatalógusában." + "Szoba közzététele" + "A szobacímek a szobák megtalálásának és elérésnek módjai. Ez azt is biztosítja, hogy könnyen megoszthatja a szobáját másokkal. +A cím szükséges ahhoz is, hogy a nyilvános szoba láthatóvá váljon a(z) %1$s kiszolgáló nyilvános szobakatalógusában." + "Biztonság és adatvédelem" + "Csatlakozás kérése" + "Titkosítás" + "Bárki" + "Szoba láthatósága" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-in/translations.xml b/features/securityandprivacy/impl/src/main/res/values-in/translations.xml new file mode 100644 index 0000000000..836ad66302 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-in/translations.xml @@ -0,0 +1,35 @@ + + + "Anda akan memerlukan alamat ruangan untuk membuatnya terlihat dalam direktori." + "Alamat ruangan" + "Tambahkan alamat ruangan" + "Siapa pun dapat meminta untuk bergabung dengan ruangan tetapi administrator atau moderator harus menerima permintaan tersebut." + "Ya, aktifkan enkripsi" + "Setelah diaktifkan, encryption untuk sebuah ruangan tidak dapat dinonaktifkan, Riwayat pesan hanya akan terlihat oleh anggota ruangan sejak mereka diundang atau sejak mereka bergabung dengan ruangan tersebut. +Tidak ada orang lain selain anggota ruangan yang dapat membaca pesan. Hal ini dapat mencegah bot dan jembatan bekerja dengan benar. +Kami tidak menyarankan untuk mengaktifkan enkripsi untuk ruangan yang dapat ditemukan dan diikuti oleh siapa pun." + "Aktifkan enkripsi?" + "Setelah diaktifkan, enkripsi tidak dapat dinonaktifkan." + "Aktifkan enkripsi ujung ke ujung" + "Siapa pun dapat menemukan dan bergabung" + "Orang hanya dapat bergabung jika mereka diundang" + "Hanya undangan" + "Akses ruangan" + "Space saat ini tidak didukung" + "Anggota space" + "Anda memerlukan alamat ruangan agar dapat membuatnya terlihat di direktori ruangan." + "Izinkan ruangan ini ditemukan dengan mencari direktori ruangan %1$s publik" + "Terlihat di direktori ruangan publik" + "Siapa yang bisa membaca riwayat" + "Hanya anggota sejak mereka diundang" + "Hanya anggota sejak memilih opsi ini" + "Alamat ruangan adalah cara untuk menemukan dan mengakses ruangan. Ini juga memastikan Anda dapat dengan mudah berbagi ruangan dengan orang lain. Anda dapat memilih untuk menerbitkan ruangan Anda di direktori ruangan publik homeserver Anda." + "Penerbitan ruangan" + "Alamat ruangan adalah cara untuk menemukan dan mengakses ruangan. Hal ini juga memastikan Anda dapat dengan mudah berbagi ruangan dengan orang lain. +Alamat ini juga diperlukan untuk membuat ruangan terlihat di %1$s direktori ruangan publik." + "Keamanan & privasi" + "Minta untuk bergabung" + "Enkripsi" + "Siapa pun" + "Keterlihatan ruangan" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-it/translations.xml b/features/securityandprivacy/impl/src/main/res/values-it/translations.xml new file mode 100644 index 0000000000..2148691b24 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-it/translations.xml @@ -0,0 +1,37 @@ + + + "Avrai bisogno di un indirizzo della stanza per renderla visibile nell\'elenco." + "Indirizzo della stanza" + "Aggiungi l\'indirizzo della stanza" + "Chiunque può chiedere di entrare nella stanza, ma un amministratore o un moderatore dovrà accettare la richiesta." + "Sì, attiva la crittografia" + "Una volta attivata, la crittografia di una stanza non può essere disattivata, la cronologia dei messaggi sarà visibile solo ai membri della stanza da quando sono stati invitati o da quando sono entrati nella stanza. +Nessuno, oltre ai membri della stanza, sarà in grado di leggere i messaggi. Ciò potrebbe impedire ai bot e ai bridge di funzionare correttamente. +Non consigliamo di attivare la crittografia per le stanze che chiunque può trovare e in cui può entrare." + "Attivare la crittografia?" + "Una volta attivata, la crittografia non può essere disattivata." + "Attiva la crittografia end-to-end" + "Chiunque può trovare ed entrare" + "Chiunque" + "Le persone possono partecipare solo se invitate" + "Solo su invito" + "Accesso alla stanza" + "Gli spazi non sono attualmente supportati" + "Membri dello spazio" + "Per rendere visibile la stanza nell\'elenco delle stanze, è necessario l\'indirizzo della stanza." + "Indirizzo della stanza" + "Consenti la ricerca di questa stanza effettuando una ricerca nell\'elenco delle stanze pubbliche di %1$s" + "Visibile nell\'elenco delle stanze pubbliche" + "Chi può leggere la cronologia messaggi" + "Solo membri da quando sono stati invitati" + "Solo membri da dopo aver selezionato questa opzione" + "Gli indirizzi delle stanze sono modi per trovare e accedervi. In questo modo puoi anche condividere facilmente la tua stanze con altri. +Puoi scegliere di pubblicare la tua stanza nell\'elenco delle stanza pubbliche dell\'homeserver." + "Pubblicazione della stanza" + "Gli indirizzi delle stanze sono modi per trovare e accedere a queste ultime. Questo assicura anche che tu possa condividere facilmente la tua stanza con altri. L\'indirizzo è anche necessario per rendere la stanza visibile in %1$s nell\'elenco delle stanze pubbliche." + "Sicurezza e privacy" + "Chiedi di entrare" + "Crittografia" + "Chiunque" + "Visibilità della stanza" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-ko/translations.xml b/features/securityandprivacy/impl/src/main/res/values-ko/translations.xml new file mode 100644 index 0000000000..b144b6bdde --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-ko/translations.xml @@ -0,0 +1,36 @@ + + + "디렉토리에 표시하려면 방 주소가 필요합니다." + "방 주소" + "방 주소 추가" + "누구나 방에 참여 요청을 할 수 있지만, 관리자나 운영자가 요청을 수락해야 합니다." + "예, 암호화 활성화" + "일단 활성화되면, 방의 암호화는 비활성화할 수 없습니다. 메시지 기록은 방에 초대된 후 또는 방에 참여한 이후부터 방 구성원만 볼 수 있습니다. +방 구성원 외에는 아무도 메시지를 읽을 수 없습니다. 이로 인해 봇과 브리지가 제대로 작동하지 않을 수 있습니다. +누구나 찾고 참여할 수 있는 방에는 암호화를 활성화하지 않는 것이 좋습니다." + "암호화 활성화?" + "일단 활성화되면, 암호화는 비활성화할 수 없습니다." + "종단간 암호화 활성화" + "누구나 찾을 수 있고 참여할 수 있습니다." + "초대받은 사용자만 가입할 수 있습니다." + "초대 전용" + "방 액세스" + "스페이스는 현재 지원되지 않습니다" + "스페이스 멤버들" + "방 디렉토리에 표시하려면 방 주소가 필요합니다." + "%1$s 공개 방 디렉토리에서 이 방을 검색할 수 있도록 허용합니다" + "공개 룸 디렉토리에 표시됨" + "누가 기록을 읽을 수 있는가" + "초대받은 회원만 이용 가능합니다" + "이 옵션을 선택한 회원만 이용 가능합니다." + "방 주소는 방을 찾고 액세스하는 방법입니다. 이를 통해 다른 사람들과 방을 쉽게 공유할 수 있습니다. +홈서버의 공개 방 디렉토리에 방을 공개할지 여부를 선택할 수 있습니다." + "방 게시" + "방 주소는 방을 찾고 액세스하는 방법입니다. 또한 이 주소를 사용하면 다른 사람들과 방을 쉽게 공유할 수 있습니다. +%1$s 의 공개 방 디렉토리에서 방을 표시하려면 이 주소도 필요합니다." + "보안 및 개인정보 보호" + "참가 요청" + "암호화" + "누구나" + "방 표시 여부" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-nb/translations.xml b/features/securityandprivacy/impl/src/main/res/values-nb/translations.xml new file mode 100644 index 0000000000..02f2163c51 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-nb/translations.xml @@ -0,0 +1,36 @@ + + + "Du trenger en adresse til rommet for å gjøre det synlig i katalogen." + "Romadresse" + "Legg til romadresse" + "Alle kan be om å bli med i rommet, men en administrator eller moderator må godta forespørselen." + "Ja, aktiver kryptering" + "Når kryptering for et rom er aktivert, kan den ikke deaktiveres. Meldingshistorikken vil bare være synlig for rommedlemmer siden de ble invitert eller siden de ble med i rommet. +Ingen andre enn rommedlemmene vil kunne lese meldingene. Dette kan føre til at bots og broer ikke fungerer som de skal. +Vi anbefaler ikke å aktivere kryptering for rom som hvem som helst kan finne og bli med i." + "Vil du aktivere kryptering?" + "Når kryptering er aktivert, kan det ikke deaktiveres." + "Aktiver ende-til-ende-kryptering" + "Alle kan finne og bli med" + "Folk kan bare bli med hvis de er invitert" + "Kun for inviterte" + "Tilgang til rom" + "Områder støttes ikke for øyeblikket" + "Medlemmer av område" + "Du trenger en adresse til rommet for å gjøre rommet synlig i romkatalogen." + "Tillat at dette rommet blir funnet ved å søke %1$s offentlig romkatalog" + "Synlig i offentlig romkatalog" + "Hvem kan lese historikk" + "Medlemmer bare siden de ble invitert" + "Kun medlemmer siden du valgte dette alternativet" + "Romadresser er måter å finne og få tilgang til rom på. Dette sikrer også at du enkelt kan dele rommet ditt med andre. +Du kan velge å publisere rommet ditt i hjemeserverens offentlige romkatalog." + "Publisering av rom" + "Romadresser er en måte å finne og få tilgang til rommene på. Dette sikrer også at du enkelt kan dele rommet ditt med andre. +Adressen er også nødvendig for å gjøre rommet synlig i den offentlige romkatalogen på %1$s." + "Sikkerhet og personvern" + "Be om å bli med" + "Kryptering" + "Alle" + "Romsynlighet" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-nl/translations.xml b/features/securityandprivacy/impl/src/main/res/values-nl/translations.xml new file mode 100644 index 0000000000..3913599edb --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-nl/translations.xml @@ -0,0 +1,5 @@ + + + "Vraag om toe te treden" + "Iedereen" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-pl/translations.xml b/features/securityandprivacy/impl/src/main/res/values-pl/translations.xml new file mode 100644 index 0000000000..8cad565318 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-pl/translations.xml @@ -0,0 +1,38 @@ + + + "Aby pokój był widoczny w katalogu, potrzebny jest adres pokoju." + "Adres pokoju" + "Dodaj adres pokoju" + "Każdy może poprosić o dołączenie do pokoju, ale administrator lub moderator będzie musiał zatwierdzić żądanie." + "Tak, włącz szyfrowanie" + "Po włączeniu szyfrowanie pokoju nie może zostać wyłączone, a historia wiadomości będzie widoczna tylko dla członków od momentu, w którym dołączyli lub zostali zaproszeni. +Nikt poza członkami pokoju nie będzie mógł czytać wiadomości. Może to wpłynąć na prawidłowe działanie botów lub mostków. +Odradzamy włączanie szyfrowania dla pokoi, które każdy może znaleźć i do których każdy może dołączyć." + "Włączyć szyfrowanie?" + "Po włączeniu szyfrowania nie można wyłączyć." + "Włącz szyfrowanie end-to-end" + "Każdy może znaleźć i dołączyć" + "Każdy" + "Tylko osoby z zaproszeniem mogą dołączyć" + "Tylko zaproszenie" + "Dostęp do pokoju" + "Przestrzenie nie są obecnie wspierane" + "Członkowie przestrzeni" + "Aby pokój był widoczny w katalogu pokoi, potrzebny jest adres pokoju." + "Adres pokoju" + "Zezwól na znalezienie tego pokoju wyszukując %1$s w katalogu pokoi publicznych" + "Widoczny w katalogu pokoi publicznych" + "Kto może czytać historię" + "Od momentu kiedy członkowie zostali zaproszeni" + "Członkowie od momentu włączenia tej opcji" + "Adresy pokoju umożliwiają łatwe znalezienie i dołączenie do pokojów. +Również możesz się zdecydować na upublicznienie Twojego serwera w katalogu pokoi publicznych." + "Publikowanie pokoju" + "Adresy pokoju umożliwiają łatwe znalezienie i dołączenie do pokojów. +Dodatkowo adres pokoju jest wymagany, aby pomieszczenie było widoczne w katalogu pokoi publicznych %1$s." + "Bezpieczeństwo i prywatność" + "Poproś o dołączenie" + "Szyfrowanie" + "Wszyscy" + "Widoczność pomieszczenia" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml b/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml new file mode 100644 index 0000000000..980fb118fb --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml @@ -0,0 +1,36 @@ + + + "Você precisará de um endereço de sala para torná-la visível no diretório." + "Endereço da sala" + "Adicionar endereço da sala" + "Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou moderador terá que aceitar o pedido." + "Sim, ativar a criptografia" + "Uma vez ativada, a criptografia de uma sala não pode ser desativada. O histórico de mensagens só será visível para os membros da sala desde que foram convidados ou desde que entraram na sala. +Ninguém além dos membros da sala poderá ler as mensagens. Isso pode impedir que os bots e as pontes funcionem corretamente. +Não recomendamos que você ative a criptografia para salas que qualquer pessoa possa encontrar e participar." + "Ativar a criptografia?" + "Uma vez ativada, a criptografia não poderá ser desativada." + "Ativar a criptografia de ponta a ponta" + "Qualquer um pode encontrar e entrar" + "As pessoas só podem participar se forem convidadas" + "Somente para convidados" + "Acesso à sala" + "No momento, não há suporte aos espaços" + "Membros do espaço" + "Você precisará de um endereço de sala para torná-la visível no diretório de salas." + "Permitir que esta sala seja encontrada pesquisando diretório de salas públicas de %1$s" + "Visível no diretório de salas públicas" + "Quem pode ler o histórico" + "Somente membros, desde que foram convidados" + "Somente para membros após selecionar esta opção" + "Os endereços das salas são formas de encontrar e acessar as salas. Isso também garante que você possa compartilhar facilmente sua sala com outras pessoas. +Você pode optar por publicar sua sala no diretório público de salas do seu servidor-casa." + "Publicação da sala" + "Os endereços das salas são formas de encontrar e acessar as salas. Isso também garante que você possa compartilhar facilmente sua sala com outras pessoas. +O endereço também é necessário para que você possa ver a sala no diretório público de salas do %1$s." + "Segurança e privacidade" + "Pedir para entrar" + "Criptografia" + "Qualquer pessoa" + "Visibilidade da sala" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-pt/translations.xml b/features/securityandprivacy/impl/src/main/res/values-pt/translations.xml new file mode 100644 index 0000000000..cdf157ab11 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-pt/translations.xml @@ -0,0 +1,38 @@ + + + "É necessário um endereço para tornar a sala visível no diretório." + "Endereço da sala" + "Adicionar endereço de sala" + "Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou moderador tem que aceitar o pedido." + "Sim, ativar cifragem" + "Uma vez ativada, a cifragem não pode ser desativada. O histórico de mensagens só será visível a membros a partir do momento em que foram convidados ou que entraram na sala. +Ninguém além dos membros poderão ler quaisquer mensagens. Isto pode impedir que robôs (\"bots\") e pontes (\"bridges\") funcionem devidamente. +Não recomendamos ativar a cifragem em salas que qualquer pessoa possa encontrar e entrar." + "Ativar cifragem?" + "Uma vez ativada, a cifragem não pode ser desativada." + "Ativar cifragem ponta-a-ponta" + "Qualquer pessoa pode encontrar a sala e entrar" + "Qualquer pessoa" + "Só é possível entrar tendo um convite" + "Apenas por convite" + "Acesso à sala" + "Os espaços ainda não estão implementados" + "Membros do espaço" + "É necessário um endereço para tornar a sala visível no diretório." + "Endereço da sala" + "Permite que esta sala seja encontrada através do diretório público do %1$s." + "Visível no diretório público de salas" + "Quem pode ler o histórico de mensagens" + "Apenas membros, desde o momento em que forem convidados" + "Apenas membros, desde o memento em que esta opção for selecionada" + "Estes endereços permitem encontrar e aceder a sala, bem como a sua fácil partilha com outros. +Podes escolher publicar a sala no diretório público do teu servidor." + "Publicar sala" + "Estes endereços permitem encontrar e aceder a sala, bem como a sua fácil partilha com outros. +Além disso, é necessário ter endereço para publicar a sala no diretório público do %1$s." + "Segurança e privacidade" + "Pedir para participar" + "Cifragem" + "Qualquer pessoa" + "Visibilidade da sala" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml b/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml new file mode 100644 index 0000000000..2bd0e41582 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml @@ -0,0 +1,36 @@ + + + "Veți avea nevoie de o adresă de cameră pentru a o face vizibilă în director." + "Adresa camerei" + "Adăugați adresa camerei" + "Oricine poate cere să se alăture camerei, dar un administrator sau moderator va trebui să accepte cererea." + "Da, activați criptarea" + "Odată activată, criptarea pentru o cameră nu poate fi dezactivată. Mesajele anterioare vor fi vizibile numai pentru membrii camerei de la momentul la care au fost invitați sau de la momentul la care s-au alăturat camerei. +Nimeni în afară de membrii camerei nu va putea citi messaje. Acest lucru poate împiedica funcționarea corectă a boților și a punților. +Nu recomandăm activarea criptării pentru camerele pe care oricine le poate găsi și la care se poate alătura." + "Activați criptarea?" + "Odată activată, criptarea nu poate fi dezactivată." + "Activați criptarea end-to-end" + "Oricine poate găsi și alătura camerei" + "Persoanele se pot alătura numai dacă invitate" + "Doar pe bază de invitație" + "Acces la cameră" + "Spațiile nu sunt momentan suportate." + "Membrii spațiului" + "Veți avea nevoie de o adresă de cameră pentru a o face vizibilă în directorul de camere." + "Permiteți găsirea acestei camere prin căutarea în directorul de camere publice al %1$s" + "Vizibilă în directorul de camere publice" + "Cine poate citi mesajele anterioare" + "Doar pentru membri, de la momentul în care au fost invitați" + "Doar pentru membri, după selectarea acestei opțiuni" + "Adresele camerelor sunt modalități de a găsi și accesa camere. Acest lucru vă asigură, de asemenea, că puteți partaja cu ușurință camera dumneavoastră cu alte persoane. +Puteți alege să publicați camera în directorul public al camerelor serverului dumneavoastră." + "Publicare cameră" + "Adresele camerelor sunt modalități de a găsi și accesa camerele. Acest lucru vă asigură, de asemenea, că puteți partaja cu ușurință camera dvs. cu alte persoane. +Adresa este necesară și pentru ca camera să fie vizibilă în directorul public de camere al %1$s." + "Securitate & confidențialitate" + "Cereți să vă alăturați" + "Criptare" + "Oricine" + "Vizibilitatea camerei" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-ru/translations.xml b/features/securityandprivacy/impl/src/main/res/values-ru/translations.xml new file mode 100644 index 0000000000..1a54034ee5 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-ru/translations.xml @@ -0,0 +1,40 @@ + + + "Вам понадобится адрес комнаты, чтобы сделать ее видимой в каталоге." + "Редактировать адрес комнаты" + "Добавить адрес комнаты" + "Любой желающий может подать заявку на присоединение к комнате, но администратор должен будет принять запрос." + "Да, включить шифрование" + "Шифрование комнаты нельзя будет отключить, история сообщений будет видна только участникам комнаты с момента их приглашения или с момента присоединения к комнате. +Никто, кроме членов комнаты, не сможет читать сообщения. Это может помешать ботам и мостам работать корректно. +Мы не рекомендуем включать шифрование для комнат, в которые может найти и присоединиться любой желающий." + "Включить шифрование?" + "После включения, шифрование не может быть отключено." + "Включить сквозное шифрование" + "Любой желающий может найти и присоединиться" + "Публичный" + "Присоединиться могут только приглашенные люди." + "Только по приглашению" + "Доступ" + "Пространства в настоящее время не поддерживаются." + "Участники пространства" + "Вам необходимо добавить адрес комнаты, чтобы сделать ее видимой в каталоге." + "Вам понадобится адрес комнаты, чтобы сделать ее видимой в каталоге комнат." + "Опубликованный адрес" + "Опубликовать %1$s в каталоге публичных комнат" + "Разрешить поиск в публичном каталоге." + "Доступна в списке публичных комнат" + "Кто может читать историю" + "Участники только с тех пор, как они были приглашены" + "Только для участников с момента выбора этой опции" + "Адреса комнат — это способ найти комнату и получить к ней доступ. Это также гарантирует, что вы сможете легко поделиться своей комнатой с другими. +Вы можете опубликовать свою комнату в каталоге общедоступных комнат на домашнем сервере." + "Публикация комнат" + "Адреса комнат — это способ найти комнату и получить к ним доступ. Это также гарантирует, что вы сможете легко поделиться своей комнатой с другими. +Адрес также необходим для отображения комнаты в каталоге %1$s общедоступных комнат." + "Безопасность и конфиденциальность" + "Попросить присоединиться" + "Шифрование" + "Любой" + "Видимость комнаты" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-sk/translations.xml b/features/securityandprivacy/impl/src/main/res/values-sk/translations.xml new file mode 100644 index 0000000000..287fa1f442 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-sk/translations.xml @@ -0,0 +1,38 @@ + + + "Budete potrebovať adresu miestnosti, aby bola viditeľná v adresári." + "Adresa miestnosti" + "Pridať adresu miestnosti" + "Ktokoľvek môže požiadať o pripojenie do miestnosti, ale správca alebo moderátor bude musieť žiadosť prijať." + "Áno, povoliť šifrovanie" + "Po aktivácii nie je možné zakázať šifrovanie pre miestnosť. História správ bude viditeľná len pre členov miestnosti, odkedy boli pozvaní alebo keď vstúpili do miestnosti. +Nikto okrem členov miestnosti nebude môcť čítať správy. +To môže brániť správnemu fungovaniu robotov a premostení. Neodporúčame povoliť šifrovanie pre miestnosti, ktoré môže ktokoľvek nájsť a pripojiť sa k nim." + "Povoliť šifrovanie?" + "Po zapnutí už šifrovanie nie je možné vypnúť." + "Povoliť end-to-end šifrovanie" + "Ktokoľvek môže nájsť a pripojiť sa" + "Ktokoľvek" + "Ľudia sa môžu pripojiť len vtedy, ak sú pozvaní" + "Iba na pozvánku" + "Prístup do miestnosti" + "Priestory momentálne nie sú podporované" + "Členovia priestoru" + "Budete potrebovať adresu miestnosti, aby bola viditeľná v adresári miestností." + "Adresa miestnosti" + "Umožniť vyhľadanie tejto miestnosti v adresári verejných miestností %1$s" + "Viditeľné v adresári verejných miestností" + "Kto môže čítať históriu" + "Len pre členov, odkedy boli pozvaní" + "Len členovia od zvolenia tejto možnosti" + "Adresy miestností predstavujú spôsoby, ako nájsť a získať prístup k miestnostiam. To tiež zaisťuje, že môžete jednoducho zdieľať svoju miestnosť s ostatnými. +Môžete sa rozhodnúť zverejniť svoju miestnosť v adresári verejných miestností vášho domovského servera." + "Zverejnenie miestnosti" + "Adresy miestností predstavujú spôsoby, ako nájsť a získať prístup k miestnostiam. Toto tiež zaisťuje, že môžete jednoducho zdieľať svoju miestnosť s ostatnými. +Adresa je tiež potrebná, aby bola miestnosť viditeľná v adresári verejných miestností %1$s." + "Bezpečnosť a súkromie" + "Požiadať o pripojenie" + "Šifrovanie" + "Ktokoľvek" + "Viditeľnosť miestnosti" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-sv/translations.xml b/features/securityandprivacy/impl/src/main/res/values-sv/translations.xml new file mode 100644 index 0000000000..b8d76de9bf --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-sv/translations.xml @@ -0,0 +1,37 @@ + + + "Du behöver en rumsadress för att göra den synlig i katalogen." + "Rumsadress" + "Lägg till rumsadress" + "Vem som helst kan be om att gå med i rummet men en administratör eller moderator måste acceptera begäran." + "Ja, aktivera kryptering" + "När det är aktiverat kan kryptering för ett rum inte inaktiveras, meddelandehistoriken visas bara för rumsmedlemmar sedan de blev inbjudna eller sedan de gick med i rummet. +Ingen förutom rumsmedlemmarna kommer att kunna läsa meddelanden. Detta kan förhindra att bots och bridges fungerar korrekt. +Vi rekommenderar inte att aktivera kryptering för rum som vem som helst kan hitta och gå med i." + "Aktivera kryptering?" + "Efter aktivering kan kryptering inte inaktiveras." + "Aktivera totalsträckskryptering" + "Vem som helst kan hitta och gå med" + "Vem som helst" + "Användare kan bara gå med om de är inbjudna" + "Endast inbjudan" + "Tillgång till rum" + "Utrymmen stöds för närvarande inte" + "Utrymmesmedlemmar" + "Du behöver en rumsadress för att göra den synlig i rumskatalogen." + "Tillåt att detta rum hittas genom att söka i den offentliga rumskatalogen på %1$s" + "Synlig i katalogen för offentliga rum" + "Vem kan läsa historik" + "Endast medlemmar sedan de bjöds in" + "Endast medlemmar sedan det här alternativet har valts" + "Rumsadresser är sätt att hitta och komma åt rum. Detta säkerställer också att du enkelt kan dela ditt rum med andra. +Du kan välja att publicera ditt rum i din hemservers offentliga rumskatalog." + "Rumspublicering" + "Rumsadresser är sätt att hitta och komma åt rum. Detta säkerställer också att du enkelt kan dela ditt rum med andra. +Adressen krävs också för att göra rummet synligt i%1$s katalog för offentliga rum." + "Säkerhet och sekretess" + "Be om att gå med" + "Kryptering" + "Vem som helst" + "Rumssynlighet" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-tr/translations.xml b/features/securityandprivacy/impl/src/main/res/values-tr/translations.xml new file mode 100644 index 0000000000..959833c7b6 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-tr/translations.xml @@ -0,0 +1,38 @@ + + + "Dizinde görünür hale getirmek için bir oda adresine ihtiyacınız olacak." + "Oda adresi" + "Oda adresi ekle" + "Herkes odaya katılma isteğinde bulunabilir ancak bir yönetici veya moderatörün isteği kabul etmesi gerekir." + "Evet, şifrelemeyi etkinleştir" + "Etkinleştirildikten sonra, bir oda için şifreleme devre dışı bırakılamaz, Mesaj geçmişi yalnızca davet edildiklerinden veya odaya katıldıklarından beri oda üyeleri için görünür olacaktır. +Oda üyeleri dışında hiç kimse mesajları okuyamayacaktır. Bu, botların ve köprülerin düzgün çalışmasını engelleyebilir. +Herkesin bulabileceği ve katılabileceği odalar için şifrelemenin etkinleştirilmesini önermiyoruz." + "Şifrelemeyi etkinleştir?" + "Açıldıktan donra şifreleme kapatılamaz." + "Uçtan uca şifrelemeyi etkinleştir" + "Herkes bulabilir ve katılabilir" + "Herkes" + "İnsanlar yalnızca davet edildiklerinde katılabilirler" + "Yalnızca davet" + "Oda Erişimi" + "Alanlar şu anda desteklenmiyor" + "Alan üyeleri" + "Oda dizininde görünür kılmak için bir oda adresine ihtiyacınız olacaktır." + "Oda adresi" + "Bu odanın %1$s genel oda dizininde arama yapılarak bulunmasına izin verin" + "Genel oda dizininde görünür" + "Geçmişi kimler okuyabilir ?" + "Sadece üyeler (davet edildiklerinden beri)" + "Bu seçeneği seçtiğinden beri yalnızca üyeler" + "Oda adresleri, odaları bulmanın ve odalara erişmenin yoludur. Bu aynı zamanda odanızı başkalarıyla kolayca paylaşabilmenizi sağlar. +Odanızı ana sunucunuzun genel oda dizininde yayınlamayı seçebilirsiniz." + "Oda yayınlama" + "Oda adresleri, odaları bulmanın ve odalara erişmenin yollarıdır. Bu aynı zamanda odanızı başkalarıyla kolayca paylaşabilmenizi sağlar. +Adres, odayı %1$s genel oda dizininde görünür kılmak için de gereklidir." + "Güvenlik ve gizlilik" + "Katılmak için sor" + "Şifreleme" + "Herkes" + "Oda görünürlüğü" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-uk/translations.xml b/features/securityandprivacy/impl/src/main/res/values-uk/translations.xml new file mode 100644 index 0000000000..b631ee092b --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-uk/translations.xml @@ -0,0 +1,38 @@ + + + "Вам знадобиться адреса кімнати, щоб зробити її видимою в каталозі." + "Адреса кімнати" + "Додати адресу кімнати" + "Будь-хто може надіслати запит приєднатися до кімнати, але адміністратор або модератор повинні прийняти запит." + "Так, увімкнути шифрування" + "Після ввімкнення шифрування кімнати, його неможливо вимкнути, історію повідомлень бачитимуть лише учасники кімнати, яких було запрошено або які приєдналися до кімнати. +Ніхто, крім учасників кімнати, не зможе прочитати повідомлення. Це може перешкоджати коректній роботі ботів і мостів. +Ми не радимо вмикати шифрування для кімнат, які будь-хто може знайти та до яких може приєднатися всі." + "Увімкнути шифрування?" + "Після ввімкнення шифрування неможливо вимкнути." + "Увімкнути наскрізне шифрування" + "Будь-хто може знайти та приєднатися." + "Будь-хто" + "Люди можуть приєднатися, лише якщо їх запросили" + "Лише запрошені" + "Доступ до кімнати" + "Простори наразі не підтримуються" + "Учасники простору" + "Вам знадобиться адреса кімнати, щоб зробити її видимою в каталозі кімнат." + "Адреса кімнати" + "Дозвольте, щоб цю кімнату можна було знайти за допомогою пошуку в каталозі загальнодоступних кімнат %1$s " + "Видима в каталозі загальнодоступних кімнат" + "Хто може читати історію" + "Лише учасники з моменту запрошення" + "Лише учасники після вибору цього параметра" + "Адреси кімнат — це спосіб знайти кімнату та отримати до неї доступ. Це також гарантує, що ви можете легко поділитися своєю кімнатою з іншими. +Ви можете опублікувати свою кімнату в каталозі загальнодоступних кімнат вашого домашнього сервера." + "Публікація в кімнаті" + "Адреси кімнат — це спосіб знайти та отримати доступ до кімнат. Це також гарантує, що ви зможете легко поділитися своєю кімнатою з іншими. +Адреса також необхідна, щоб зробити кімнату видимою в каталозі загальнодоступних кімнат %1$s." + "Безпека й приватність" + "Запросити приєднатися" + "Шифрування" + "Кожний" + "Видимість кімнати" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-uz/translations.xml b/features/securityandprivacy/impl/src/main/res/values-uz/translations.xml new file mode 100644 index 0000000000..157e8f8418 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-uz/translations.xml @@ -0,0 +1,7 @@ + + + "Qo‘shilishni so‘rang" + "Shifrlash" + "Har kim" + "Xonaning ko‘rinishi" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-zh-rTW/translations.xml b/features/securityandprivacy/impl/src/main/res/values-zh-rTW/translations.xml new file mode 100644 index 0000000000..44a21456f4 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-zh-rTW/translations.xml @@ -0,0 +1,38 @@ + + + "您需要聊天室地址才能在目錄中顯示它。" + "聊天室地址" + "新增聊天室地址" + "任何人都可以要求加入聊天室,但管理員必須接受請求。" + "是的,啟用加密" + "啟用後就無法停用聊天室的加密,只有受邀的聊天室成員或加入聊天室後才能看到訊息歷史紀錄。 +除了聊天室成員以外,任何人都不能讀取訊息。這可能會讓機器人與橋接無法正常運作。 +我們不建議對任何人都可以找到並加入的聊天室啟用加密。" + "啟用加密?" + "一旦啟用就無法停用加密。" + "啟用端到端加密" + "任何人都可以找到並加入" + "任何人" + "人們僅有受到邀請時才能加入" + "僅限邀請" + "聊天室存取權" + "目前不支援空間" + "空間成員" + "您需要聊天室地址才能在聊天室目錄中顯示。" + "聊天室地址" + "允許透過搜尋 %1$s 公開聊天室目錄找到此聊天室" + "在公開聊天室目錄中可見" + "誰可以讀取歷史紀錄" + "僅在成員被邀請後" + "選取此選項後僅限成員" + "聊天室地址是尋找與存取聊天室的方法。也確保您可以輕鬆與其他人分享聊天室。 +您可以選擇在家伺服器公開聊天室目錄中發佈您的聊天室。" + "聊天室發佈" + "聊天室地址是尋找與存取聊天室的方法。也確保您可以輕鬆與其他人分享聊天室。 +若要讓聊天室在 %1$s 公開聊天室目錄中可見,地址也是必要的。" + "安全與隱私" + "要求加入" + "加密" + "任何人" + "聊天室能見度" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values-zh/translations.xml b/features/securityandprivacy/impl/src/main/res/values-zh/translations.xml new file mode 100644 index 0000000000..1dd91a684d --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values-zh/translations.xml @@ -0,0 +1,38 @@ + + + "你需要房间地址才能使其在目录中可见。" + "房间地址" + "添加房间地址" + "任何人都可以请求加入房间,但必须由管理员或版主接受请求。" + "是的,启用加密" + "一旦启用,就不能再禁用房间的加密功能。消息历史记录只能在房间成员被邀请或加入房间后才可见。 +除房间成员外,任何人都无法阅读信息。这可能会妨碍机器人和网桥正常工作。 +我们不建议对任何人都能找到并加入的房间启用加密。" + "启用加密?" + "加密一旦启用,就无法禁用。" + "启用端到端加密" + "任何人都可以找到并加入" + "任何人" + "只有受邀者才能加入" + "仅限邀请" + "房间访问权限" + "目前不支持空间" + "空间成员" + "你需要有房间地址才能使其在房间目录中可见。" + "房间地址" + "允许通过搜索 %1$s 的公共房间目录来发现此房间" + "在公共房间目录中可见" + "谁可以读取历史记录" + "仅限被邀请的成员" + "仅自选择此选项以来的成员" + "房间地址是查找和访问房间的方式。这也确保你可以轻松地向他人分享房间。 +你可以选择在你服务器的公共房间目录中发布你的房间。" + "房间发布" + "房间地址是查找和访问房间的方式。这也确保你可以轻松地向他人分享房间。 +在 %1$s 的公共房间目录中显示该房间时也需要地址。" + "安全与隐私" + "请求加入" + "加密" + "任何人" + "房间可见性" + \ No newline at end of file diff --git a/features/securityandprivacy/impl/src/main/res/values/localazy.xml b/features/securityandprivacy/impl/src/main/res/values/localazy.xml new file mode 100644 index 0000000000..b0e8195733 --- /dev/null +++ b/features/securityandprivacy/impl/src/main/res/values/localazy.xml @@ -0,0 +1,40 @@ + + + "You’ll need an address in order to make it visible in the public directory." + "Edit address" + "Add room address" + "Anyone can request access but an administrator must accept the request." + "Ask to join" + "Yes, enable encryption" + "Once enabled, encryption for a room cannot be disabled, Message history will only be visible for room members since they were invited or since they joined the room. +No one besides the room members will be able to read messages. This may prevent bots and bridges to work correctly. +We do not recommend enabling encryption for rooms that anyone can find and join." + "Enable encryption?" + "Once enabled, encryption cannot be disabled." + "Encryption" + "Enable end-to-end encryption" + "Anyone can join." + "Public" + "Only invited people can join." + "Private" + "Access" + "Spaces are not currently supported" + "Space members" + "You’ll need an address in order to make it visible in the public directory." + "You’ll need a room address in order to make it visible in the room directory." + "Published address" + "Allow for this room to be found by searching %1$s public room directory" + "Allow to be found by searching the public directory." + "Visible in public directory" + "Anyone" + "Who can read history" + "Members only since they were invited" + "Members only since selecting this option" + "Room addresses are ways to find and access rooms. This also ensures you can easily share your room with others. +You can choose to publish your room in your homeserver public room directory." + "Room publishing" + "Room addresses are ways to find and access rooms. This also ensures you can easily share your room with others. +The address is also required to make the room visible in %1$s public room directory." + "Room visibility" + "Security & privacy" + diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/FakeSecurityAndPrivacyNavigator.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/FakeSecurityAndPrivacyNavigator.kt similarity index 90% rename from features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/FakeSecurityAndPrivacyNavigator.kt rename to features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/FakeSecurityAndPrivacyNavigator.kt index 4ba6019f77..9ca3cc5288 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/FakeSecurityAndPrivacyNavigator.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/FakeSecurityAndPrivacyNavigator.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy +package io.element.android.features.securityandprivacy.impl import io.element.android.tests.testutils.lambda.lambdaError diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt similarity index 97% rename from features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyPresenterTest.kt rename to features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt index 34edea50fb..bdae5274f0 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyPresenterTest.kt @@ -6,9 +6,13 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy +package io.element.android.features.securityandprivacy.impl import com.google.common.truth.Truth.assertThat +import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyEvents +import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyHistoryVisibility +import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyPresenter +import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyRoomAccess import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.featureflag.api.FeatureFlagService diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyViewTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt similarity index 90% rename from features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyViewTest.kt rename to features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt index 93d644121c..c7ab57a577 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/SecurityAndPrivacyViewTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy +package io.element.android.features.securityandprivacy.impl import androidx.activity.ComponentActivity import androidx.compose.ui.test.junit4.AndroidComposeTestRule @@ -14,7 +14,13 @@ import androidx.compose.ui.test.junit4.createAndroidComposeRule import androidx.compose.ui.test.onNodeWithText import androidx.compose.ui.test.performClick import androidx.test.ext.junit.runners.AndroidJUnit4 -import io.element.android.features.roomdetails.impl.R +import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyEvents +import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyHistoryVisibility +import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyRoomAccess +import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyState +import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyView +import io.element.android.features.securityandprivacy.impl.root.aSecurityAndPrivacySettings +import io.element.android.features.securityandprivacy.impl.root.aSecurityAndPrivacyState import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.tests.testutils.EnsureNeverCalled diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditBaseRoomAddressPresenterTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressPresenterTest.kt similarity index 93% rename from features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditBaseRoomAddressPresenterTest.kt rename to features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressPresenterTest.kt index 75d7b44a95..aac25ec018 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditBaseRoomAddressPresenterTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressPresenterTest.kt @@ -6,12 +6,11 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy.editroomaddress +package io.element.android.features.securityandprivacy.impl.editroomaddress import com.google.common.truth.Truth.assertThat -import io.element.android.features.roomdetails.impl.aJoinedRoom -import io.element.android.features.roomdetails.impl.securityandprivacy.FakeSecurityAndPrivacyNavigator -import io.element.android.features.roomdetails.impl.securityandprivacy.SecurityAndPrivacyNavigator +import io.element.android.features.securityandprivacy.impl.FakeSecurityAndPrivacyNavigator +import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.matrix.api.core.RoomAlias import io.element.android.libraries.matrix.api.room.JoinedRoom @@ -21,6 +20,7 @@ import io.element.android.libraries.matrix.test.AN_EXCEPTION import io.element.android.libraries.matrix.test.A_ROOM_ID import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.room.FakeJoinedRoom +import io.element.android.libraries.matrix.test.room.aRoomInfo import io.element.android.libraries.matrix.test.room.alias.FakeRoomAliasHelper import io.element.android.libraries.matrix.ui.room.address.RoomAddressValidity import io.element.android.tests.testutils.lambda.assert @@ -31,11 +31,13 @@ import kotlinx.coroutines.test.runTest import org.junit.Test import java.util.Optional -class EditBaseRoomAddressPresenterTest { +class EditRoomAddressPresenterTest { @Test fun `present - initial state no address`() = runTest { val presenter = createEditRoomAddressPresenter( - room = aJoinedRoom(displayName = "") + room = FakeJoinedRoom().apply { + givenRoomInfo(aRoomInfo(name = "")) + } ) presenter.test { with(awaitItem()) { @@ -50,9 +52,9 @@ class EditBaseRoomAddressPresenterTest { @Test fun `present - initial state address matching own homeserver`() = runTest { - val room = aJoinedRoom( - canonicalAlias = RoomAlias("#canonical:matrix.org"), - ) + val room = FakeJoinedRoom().apply { + givenRoomInfo(aRoomInfo(canonicalAlias = RoomAlias("#canonical:matrix.org"))) + } val presenter = createEditRoomAddressPresenter(room = room) presenter.test { with(awaitItem()) { @@ -67,10 +69,14 @@ class EditBaseRoomAddressPresenterTest { @Test fun `present - initial state address not matching own homeserver`() = runTest { - val room = aJoinedRoom( - displayName = "", - canonicalAlias = RoomAlias("#canonical:notmatrix.org"), - ) + val room = FakeJoinedRoom().apply { + givenRoomInfo( + aRoomInfo( + name = "", + canonicalAlias = RoomAlias("#canonical:notmatrix.org") + ) + ) + } val presenter = createEditRoomAddressPresenter(room = room) presenter.test { with(awaitItem()) { @@ -196,12 +202,13 @@ class EditBaseRoomAddressPresenterTest { val navigator = FakeSecurityAndPrivacyNavigator(closeEditRoomAddressLambda = closeEditAddressLambda) val canonicalAlias = RoomAlias("#canonical:matrix.org") - val room = aJoinedRoom( - canonicalAlias = canonicalAlias, + val room = FakeJoinedRoom( updateCanonicalAliasResult = updateCanonicalAliasResult, publishRoomAliasInRoomDirectoryResult = publishAliasInRoomDirectoryResult, removeRoomAliasFromRoomDirectoryResult = removeAliasFromRoomDirectoryResult - ) + ).apply { + givenRoomInfo(aRoomInfo(canonicalAlias = canonicalAlias)) + } val presenter = createEditRoomAddressPresenter(room = room, navigator = navigator) presenter.test { with(awaitItem()) { @@ -246,12 +253,13 @@ class EditBaseRoomAddressPresenterTest { val navigator = FakeSecurityAndPrivacyNavigator(closeEditRoomAddressLambda = closeEditAddressLambda) val canonicalAlias = RoomAlias("#canonical:notmatrix.org") - val room = aJoinedRoom( - canonicalAlias = canonicalAlias, + val room = FakeJoinedRoom( updateCanonicalAliasResult = updateCanonicalAliasResult, publishRoomAliasInRoomDirectoryResult = publishAliasInRoomDirectoryResult, removeRoomAliasFromRoomDirectoryResult = removeAliasFromRoomDirectoryResult - ) + ).apply { + givenRoomInfo(aRoomInfo(canonicalAlias = canonicalAlias)) + } val presenter = createEditRoomAddressPresenter(room = room, navigator = navigator) presenter.test { with(awaitItem()) { diff --git a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditBaseRoomAddressViewTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressViewTest.kt similarity index 97% rename from features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditBaseRoomAddressViewTest.kt rename to features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressViewTest.kt index ff6a75881b..17d6f3a88d 100644 --- a/features/roomdetails/impl/src/test/kotlin/io/element/android/features/roomdetails/impl/securityandprivacy/editroomaddress/EditBaseRoomAddressViewTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/editroomaddress/EditRoomAddressViewTest.kt @@ -6,7 +6,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.features.roomdetails.impl.securityandprivacy.editroomaddress +package io.element.android.features.securityandprivacy.impl.editroomaddress import androidx.activity.ComponentActivity import androidx.compose.ui.test.junit4.AndroidComposeTestRule @@ -29,7 +29,7 @@ import org.junit.rules.TestRule import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) -class EditBaseRoomAddressViewTest { +class EditRoomAddressViewTest { @get:Rule val rule = createAndroidComposeRule() @Test diff --git a/features/securityandprivacy/test/build.gradle.kts b/features/securityandprivacy/test/build.gradle.kts new file mode 100644 index 0000000000..903ef6d194 --- /dev/null +++ b/features/securityandprivacy/test/build.gradle.kts @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * Copyright 2025 New Vector Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +plugins { + id("io.element.android-library") +} + +android { + namespace = "io.element.android.features.securityandprivacy.test" +} + +dependencies { + implementation(projects.features.securityandprivacy.api) + implementation(projects.libraries.architecture) + implementation(projects.libraries.matrix.api) + implementation(projects.tests.testutils) +} diff --git a/features/securityandprivacy/test/src/main/kotlin/io/element/android/features/securityandprivacy/test/FakeSecurityAndPrivacyEntryPoint.kt b/features/securityandprivacy/test/src/main/kotlin/io/element/android/features/securityandprivacy/test/FakeSecurityAndPrivacyEntryPoint.kt new file mode 100644 index 0000000000..f316b2fe96 --- /dev/null +++ b/features/securityandprivacy/test/src/main/kotlin/io/element/android/features/securityandprivacy/test/FakeSecurityAndPrivacyEntryPoint.kt @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.securityandprivacy.test + +import com.bumble.appyx.core.modality.BuildContext +import com.bumble.appyx.core.node.Node +import io.element.android.features.securityandprivacy.api.SecurityAndPrivacyEntryPoint +import io.element.android.tests.testutils.lambda.lambdaError + +class FakeSecurityAndPrivacyEntryPoint : SecurityAndPrivacyEntryPoint { + override fun createNode(parentNode: Node, buildContext: BuildContext): Node { + lambdaError() + } +} diff --git a/tools/localazy/config.json b/tools/localazy/config.json index 8cb1228b94..46908438b5 100644 --- a/tools/localazy/config.json +++ b/tools/localazy/config.json @@ -377,6 +377,13 @@ "screen_room_member_list.*", "screen\\.room_member_list\\..*" ] + }, + { + "name" : ":features:securityandprivacy:impl", + "includeRegex" : [ + "screen\\.edit_room_address\\..*", + "screen\\.security_and_privacy\\..*" + ] } ] } From 2774a07b559acf598806f22094a6b4e230fd15a2 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 19 Nov 2025 14:52:59 +0100 Subject: [PATCH 066/113] change(security and privacy) : add isSpace and update state provider --- .../impl/root/SecurityAndPrivacyPresenter.kt | 1 + .../impl/root/SecurityAndPrivacyState.kt | 5 +- .../root/SecurityAndPrivacyStateProvider.kt | 109 ++++++++++-------- 3 files changed, 65 insertions(+), 50 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index 7c0c04f8c3..fa51008113 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -160,6 +160,7 @@ class SecurityAndPrivacyPresenter( isKnockEnabled = isKnockEnabled, saveAction = saveAction.value, permissions = permissions, + isSpace = roomInfo.isSpace, eventSink = ::handleEvent, ) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index be9c24dc65..06a283657b 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -22,6 +22,7 @@ data class SecurityAndPrivacyState( val showEnableEncryptionConfirmation: Boolean, val isKnockEnabled: Boolean, val saveAction: AsyncAction, + val isSpace: Boolean, private val permissions: SecurityAndPrivacyPermissions, val eventSink: (SecurityAndPrivacyEvents) -> Unit ) { @@ -38,8 +39,8 @@ data class SecurityAndPrivacyState( val showRoomAccessSection = permissions.canChangeRoomAccess val showRoomVisibilitySections = permissions.canChangeRoomVisibility && editedSettings.roomAccess != SecurityAndPrivacyRoomAccess.InviteOnly - val showHistoryVisibilitySection = permissions.canChangeHistoryVisibility - val showEncryptionSection = permissions.canChangeEncryption + val showHistoryVisibilitySection = permissions.canChangeHistoryVisibility && !isSpace + val showEncryptionSection = permissions.canChangeEncryption && !isSpace } data class SecurityAndPrivacySettings( diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt index c13fc36d34..3f55449b51 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt @@ -15,56 +15,67 @@ import io.element.android.libraries.architecture.AsyncData open class SecurityAndPrivacyStateProvider : PreviewParameterProvider { override val values: Sequence - get() = sequenceOf( - aSecurityAndPrivacyState(), - aSecurityAndPrivacyState( - editedSettings = aSecurityAndPrivacySettings( - roomAccess = SecurityAndPrivacyRoomAccess.AskToJoin - ) - ), - aSecurityAndPrivacyState( - editedSettings = aSecurityAndPrivacySettings( - roomAccess = SecurityAndPrivacyRoomAccess.Anyone, - isEncrypted = false, - ) - ), - aSecurityAndPrivacyState( - savedSettings = aSecurityAndPrivacySettings( - roomAccess = SecurityAndPrivacyRoomAccess.SpaceMember - ), - isKnockEnabled = false, - ), - aSecurityAndPrivacyState( - editedSettings = aSecurityAndPrivacySettings( - roomAccess = SecurityAndPrivacyRoomAccess.Anyone, - address = "#therapy:myserver.xyz" - ) - ), - aSecurityAndPrivacyState( - editedSettings = aSecurityAndPrivacySettings( - isVisibleInRoomDirectory = AsyncData.Loading() - ) - ), - aSecurityAndPrivacyState( - editedSettings = aSecurityAndPrivacySettings( - isVisibleInRoomDirectory = AsyncData.Success(true) - ) - ), - aSecurityAndPrivacyState( - showEncryptionConfirmation = true - ), - aSecurityAndPrivacyState( - saveAction = AsyncAction.Loading - ), - aSecurityAndPrivacyState( - savedSettings = aSecurityAndPrivacySettings( - roomAccess = SecurityAndPrivacyRoomAccess.AskToJoin - ), - isKnockEnabled = false, - ), - ) + get() = securityAndPrivacyStates(isSpace = false) + securityAndPrivacyStates(isSpace = true) } +private fun securityAndPrivacyStates(isSpace: Boolean): Sequence = sequenceOf( + aSecurityAndPrivacyState(isSpace = isSpace), + aSecurityAndPrivacyState( + editedSettings = aSecurityAndPrivacySettings( + roomAccess = SecurityAndPrivacyRoomAccess.AskToJoin, + ), + isSpace = isSpace, + ), + aSecurityAndPrivacyState( + editedSettings = aSecurityAndPrivacySettings( + roomAccess = SecurityAndPrivacyRoomAccess.Anyone, + isEncrypted = false, + ), + isSpace = isSpace, + ), + aSecurityAndPrivacyState( + savedSettings = aSecurityAndPrivacySettings( + roomAccess = SecurityAndPrivacyRoomAccess.SpaceMember + ), + isSpace = isSpace, + isKnockEnabled = false, + ), + aSecurityAndPrivacyState( + editedSettings = aSecurityAndPrivacySettings( + roomAccess = SecurityAndPrivacyRoomAccess.Anyone, + address = "#therapy:myserver.xyz" + ), + isSpace = isSpace, + ), + aSecurityAndPrivacyState( + editedSettings = aSecurityAndPrivacySettings( + isVisibleInRoomDirectory = AsyncData.Loading() + ), + isSpace = isSpace, + ), + aSecurityAndPrivacyState( + editedSettings = aSecurityAndPrivacySettings( + isVisibleInRoomDirectory = AsyncData.Success(true) + ), + isSpace = isSpace, + ), + aSecurityAndPrivacyState( + showEncryptionConfirmation = true, + isSpace = isSpace, + ), + aSecurityAndPrivacyState( + saveAction = AsyncAction.Loading, + isSpace = isSpace, + ), + aSecurityAndPrivacyState( + savedSettings = aSecurityAndPrivacySettings( + roomAccess = SecurityAndPrivacyRoomAccess.AskToJoin + ), + isSpace = isSpace, + isKnockEnabled = false, + ), +) + fun aSecurityAndPrivacySettings( roomAccess: SecurityAndPrivacyRoomAccess = SecurityAndPrivacyRoomAccess.InviteOnly, isEncrypted: Boolean = true, @@ -92,6 +103,7 @@ fun aSecurityAndPrivacyState( canChangeRoomVisibility = true ), isKnockEnabled: Boolean = true, + isSpace: Boolean = false, eventSink: (SecurityAndPrivacyEvents) -> Unit = {} ) = SecurityAndPrivacyState( editedSettings = editedSettings, @@ -101,5 +113,6 @@ fun aSecurityAndPrivacyState( saveAction = saveAction, isKnockEnabled = isKnockEnabled, permissions = permissions, + isSpace = isSpace, eventSink = eventSink ) From 355e1b2f3d18123ae2fe951a16d07e95eee2537f Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 19 Nov 2025 15:32:51 +0100 Subject: [PATCH 067/113] change(security and privacy) : makes sure room visibility sections is shown when needed --- .../impl/root/SecurityAndPrivacyState.kt | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index 06a283657b..61e8ffd17c 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -38,7 +38,10 @@ data class SecurityAndPrivacyState( }.toImmutableSet() val showRoomAccessSection = permissions.canChangeRoomAccess - val showRoomVisibilitySections = permissions.canChangeRoomVisibility && editedSettings.roomAccess != SecurityAndPrivacyRoomAccess.InviteOnly + + val showRoomVisibilitySections = permissions.canChangeRoomVisibility && + editedSettings.roomAccess.canConfigureRoomVisibility() + val showHistoryVisibilitySection = permissions.canChangeHistoryVisibility && !isSpace val showEncryptionSection = permissions.canChangeEncryption && !isSpace } @@ -72,7 +75,14 @@ enum class SecurityAndPrivacyRoomAccess { InviteOnly, AskToJoin, Anyone, - SpaceMember + SpaceMember; + + fun canConfigureRoomVisibility(): Boolean { + return when (this) { + InviteOnly, SpaceMember -> false + AskToJoin, Anyone -> true + } + } } sealed class SecurityAndPrivacyFailures : Exception() { From 6ed7a6107d82cd43ba0a9342ca72d39bd8c4b2bb Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 19 Nov 2025 15:50:07 +0100 Subject: [PATCH 068/113] change(security and privacy) : update access items --- .../impl/root/SecurityAndPrivacyView.kt | 43 +++++++++++-------- 1 file changed, 24 insertions(+), 19 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index 7eeabba3c0..4523be8d0c 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -187,11 +187,22 @@ private fun RoomAccessSection( modifier = modifier, ) { ListItem( - headlineContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_invite_only_option_title)) }, - supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_invite_only_option_description)) }, - trailingContent = ListItemContent.RadioButton(selected = edited == SecurityAndPrivacyRoomAccess.InviteOnly), - onClick = { onSelectOption(SecurityAndPrivacyRoomAccess.InviteOnly) }, + headlineContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_anyone_option_title)) }, + supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_anyone_option_description)) }, + trailingContent = ListItemContent.RadioButton(selected = edited == SecurityAndPrivacyRoomAccess.Anyone), + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Public())), + onClick = { onSelectOption(SecurityAndPrivacyRoomAccess.Anyone) }, ) + // Show space member option, but disabled as we don't support this option for now. + if (saved == SecurityAndPrivacyRoomAccess.SpaceMember) { + ListItem( + headlineContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_title)) }, + supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_description)) }, + trailingContent = ListItemContent.RadioButton(selected = edited == SecurityAndPrivacyRoomAccess.SpaceMember, enabled = false), + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Workspace())), + enabled = false, + ) + } // Show Ask to join option in two cases: // - the Knock FF is enabled // - AskToJoin is the current saved value @@ -201,24 +212,18 @@ private fun RoomAccessSection( supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_ask_to_join_option_description)) }, trailingContent = ListItemContent.RadioButton(selected = edited == SecurityAndPrivacyRoomAccess.AskToJoin), onClick = { onSelectOption(SecurityAndPrivacyRoomAccess.AskToJoin) }, + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.UserAdd())), enabled = isKnockEnabled, ) } ListItem( - headlineContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_anyone_option_title)) }, - supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_anyone_option_description)) }, - trailingContent = ListItemContent.RadioButton(selected = edited == SecurityAndPrivacyRoomAccess.Anyone), - onClick = { onSelectOption(SecurityAndPrivacyRoomAccess.Anyone) }, + headlineContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_invite_only_option_title)) }, + supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_invite_only_option_description)) }, + trailingContent = ListItemContent.RadioButton(selected = edited == SecurityAndPrivacyRoomAccess.InviteOnly), + leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Lock())), + onClick = { onSelectOption(SecurityAndPrivacyRoomAccess.InviteOnly) }, ) - // Show space member option, but disabled as we don't support this option for now. - if (saved == SecurityAndPrivacyRoomAccess.SpaceMember) { - ListItem( - headlineContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_title)) }, - supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_description)) }, - trailingContent = ListItemContent.RadioButton(selected = true, enabled = false), - enabled = false, - ) - } + } } @@ -259,7 +264,7 @@ private fun RoomAddressSection( Text(text = roomAddress ?: stringResource(R.string.screen_security_and_privacy_add_room_address_action)) }, trailingContent = if (roomAddress.isNullOrEmpty()) ListItemContent.Icon(IconSource.Vector(CompoundIcons.Plus())) else null, - supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_address_section_footer)) }, + supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_address_description)) }, onClick = onRoomAddressClick, colors = ListItemDefaults.colors(trailingIconColor = ElementTheme.colors.iconAccentPrimary), ) @@ -267,7 +272,7 @@ private fun RoomAddressSection( ListItem( headlineContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_directory_visibility_toggle_title)) }, supportingContent = { - Text(text = stringResource(R.string.screen_security_and_privacy_room_directory_visibility_section_footer, homeserverName)) + Text(text = stringResource(R.string.screen_security_and_privacy_room_directory_visibility_toggle_description, homeserverName)) }, onClick = if (isVisibleInRoomDirectory.isSuccess()) onVisibilityChange else null, trailingContent = when (isVisibleInRoomDirectory) { From 519b6c28878fb619c8049bde4473876a3e3440eb Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 19 Nov 2025 16:55:18 +0100 Subject: [PATCH 069/113] change(security and privacy) : retain state in node --- .../securityandprivacy/impl/root/SecurityAndPrivacyNode.kt | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt index 87ba27cb02..5e329a06f6 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyNode.kt @@ -9,6 +9,8 @@ package io.element.android.features.securityandprivacy.impl.root import androidx.compose.runtime.Composable +import androidx.compose.runtime.collectAsState +import androidx.compose.runtime.getValue import androidx.compose.ui.Modifier import com.bumble.appyx.core.modality.BuildContext import com.bumble.appyx.core.node.Node @@ -18,6 +20,7 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator +import io.element.android.libraries.architecture.appyx.launchMolecule import io.element.android.libraries.di.RoomScope @ContributesNode(RoomScope::class) @@ -30,9 +33,11 @@ class SecurityAndPrivacyNode( private val navigator = plugins().first() private val presenter = presenterFactory.create(navigator) + private val stateFlow = launchMolecule { presenter.present() } + @Composable override fun View(modifier: Modifier) { - val state = presenter.present() + val state by stateFlow.collectAsState() SecurityAndPrivacyView( state = state, onBackClick = this::navigateUp, From 11bd9f5e8880f3b91f5425505586a67098ddf34a Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 19 Nov 2025 16:55:27 +0100 Subject: [PATCH 070/113] change(security and privacy) : clean code --- .../impl/root/SecurityAndPrivacyPresenter.kt | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index fa51008113..e1766f3220 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -75,12 +75,11 @@ class SecurityAndPrivacyPresenter( val savedSettings by remember { derivedStateOf { - val historyVisibility = roomInfo.historyVisibility.map() SecurityAndPrivacySettings( roomAccess = roomInfo.joinRule.map(), isEncrypted = roomInfo.isEncrypted == true, isVisibleInRoomDirectory = savedIsVisibleInRoomDirectory.value, - historyVisibility = historyVisibility, + historyVisibility = roomInfo.historyVisibility.map(), address = roomInfo.firstDisplayableAlias(homeserverName)?.value, ) } From 717584f5128fd6d1d13fdc9f83e04305892793c8 Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 19 Nov 2025 21:44:39 +0100 Subject: [PATCH 071/113] change(security and privacy) : display SaveChangesDialog on exit --- .../impl/root/SecurityAndPrivacyEvents.kt | 2 + .../impl/root/SecurityAndPrivacyPresenter.kt | 15 +++++- .../impl/root/SecurityAndPrivacyState.kt | 1 + .../root/SecurityAndPrivacyStateProvider.kt | 53 ++++++++++++------- .../impl/root/SecurityAndPrivacyView.kt | 22 +++++++- 5 files changed, 72 insertions(+), 21 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvents.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvents.kt index 8119ddb0c4..2553090541 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvents.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvents.kt @@ -11,6 +11,8 @@ package io.element.android.features.securityandprivacy.impl.root sealed interface SecurityAndPrivacyEvents { data object EditRoomAddress : SecurityAndPrivacyEvents data object Save : SecurityAndPrivacyEvents + data object Exit: SecurityAndPrivacyEvents + data object DismissExitConfirmation : SecurityAndPrivacyEvents data class ChangeRoomAccess(val roomAccess: SecurityAndPrivacyRoomAccess) : SecurityAndPrivacyEvents data object ToggleEncryptionState : SecurityAndPrivacyEvents data object CancelEnableEncryption : SecurityAndPrivacyEvents diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index e1766f3220..5bcbe15f7c 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -26,6 +26,7 @@ import io.element.android.features.securityandprivacy.impl.editroomaddress.match import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissionsAsState import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData +import io.element.android.libraries.architecture.AsyncData.* import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.architecture.runUpdatingState @@ -64,6 +65,7 @@ class SecurityAndPrivacyPresenter( featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock) }.collectAsState(false) val saveAction = remember { mutableStateOf>(AsyncAction.Uninitialized) } + var confirmExitAction by remember { mutableStateOf>(AsyncAction.Uninitialized)} val homeserverName = remember { matrixClient.userIdServerName() } val syncUpdateFlow = room.syncUpdateFlow.collectAsState() val roomInfo by room.roomInfoFlow.collectAsState() @@ -133,7 +135,7 @@ class SecurityAndPrivacyPresenter( } SecurityAndPrivacyEvents.ToggleRoomVisibility -> { editedVisibleInRoomDirectory = when (val edited = editedVisibleInRoomDirectory) { - is AsyncData.Success -> AsyncData.Success(!edited.data) + is Success -> Success(!edited.data) else -> edited } } @@ -148,6 +150,16 @@ class SecurityAndPrivacyPresenter( SecurityAndPrivacyEvents.DismissSaveError -> { saveAction.value = AsyncAction.Uninitialized } + SecurityAndPrivacyEvents.Exit -> { + confirmExitAction = if (savedSettings == editedSettings || confirmExitAction.isConfirming()) { + AsyncAction.Success(Unit) + } else { + AsyncAction.ConfirmingNoParams + } + } + SecurityAndPrivacyEvents.DismissExitConfirmation -> { + confirmExitAction = AsyncAction.Uninitialized + } } } @@ -160,6 +172,7 @@ class SecurityAndPrivacyPresenter( saveAction = saveAction.value, permissions = permissions, isSpace = roomInfo.isSpace, + confirmExitAction = confirmExitAction, eventSink = ::handleEvent, ) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt index 61e8ffd17c..0671bbf163 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyState.kt @@ -22,6 +22,7 @@ data class SecurityAndPrivacyState( val showEnableEncryptionConfirmation: Boolean, val isKnockEnabled: Boolean, val saveAction: AsyncAction, + val confirmExitAction: AsyncAction, val isSpace: Boolean, private val permissions: SecurityAndPrivacyPermissions, val eventSink: (SecurityAndPrivacyEvents) -> Unit diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt index 3f55449b51..00dc175b4c 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt @@ -15,10 +15,29 @@ import io.element.android.libraries.architecture.AsyncData open class SecurityAndPrivacyStateProvider : PreviewParameterProvider { override val values: Sequence - get() = securityAndPrivacyStates(isSpace = false) + securityAndPrivacyStates(isSpace = true) + get() = commonSecurityAndPrivacyStates(isSpace = false) + + commonSecurityAndPrivacyStates(isSpace = true) + + sequenceOf( + aSecurityAndPrivacyState( + saveAction = AsyncAction.Loading, + isSpace = false, + ), + aSecurityAndPrivacyState( + saveAction = AsyncAction.Failure(SecurityAndPrivacyFailures.SaveFailed), + isSpace = false, + ), + aSecurityAndPrivacyState( + confirmExitAction = AsyncAction.ConfirmingCancellation, + isSpace = false, + ), + aSecurityAndPrivacyState( + showEncryptionConfirmation = true, + isSpace = false, + ), + ) } -private fun securityAndPrivacyStates(isSpace: Boolean): Sequence = sequenceOf( +private fun commonSecurityAndPrivacyStates(isSpace: Boolean): Sequence = sequenceOf( aSecurityAndPrivacyState(isSpace = isSpace), aSecurityAndPrivacyState( editedSettings = aSecurityAndPrivacySettings( @@ -26,6 +45,13 @@ private fun securityAndPrivacyStates(isSpace: Boolean): Sequence = AsyncAction.Uninitialized, + confirmExitAction: AsyncAction = AsyncAction.Uninitialized, permissions: SecurityAndPrivacyPermissions = SecurityAndPrivacyPermissions( canChangeRoomAccess = true, canChangeHistoryVisibility = true, @@ -103,7 +117,7 @@ fun aSecurityAndPrivacyState( canChangeRoomVisibility = true ), isKnockEnabled: Boolean = true, - isSpace: Boolean = false, + isSpace: Boolean, eventSink: (SecurityAndPrivacyEvents) -> Unit = {} ) = SecurityAndPrivacyState( editedSettings = editedSettings, @@ -111,8 +125,9 @@ fun aSecurityAndPrivacyState( homeserverName = homeserverName, showEnableEncryptionConfirmation = showEncryptionConfirmation, saveAction = saveAction, + confirmExitAction = confirmExitAction, isKnockEnabled = isKnockEnabled, permissions = permissions, isSpace = isSpace, - eventSink = eventSink + eventSink = eventSink, ) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index 4523be8d0c..a4e3396f44 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -8,6 +8,7 @@ package io.element.android.features.securityandprivacy.impl.root +import androidx.activity.compose.BackHandler import androidx.compose.foundation.layout.Arrangement import androidx.compose.foundation.layout.Column import androidx.compose.foundation.layout.ColumnScope @@ -31,12 +32,14 @@ import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.securityandprivacy.impl.R +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.coverage.ExcludeFromCoverage import io.element.android.libraries.designsystem.components.async.AsyncActionView import io.element.android.libraries.designsystem.components.async.AsyncActionViewDefaults import io.element.android.libraries.designsystem.components.button.BackButton import io.element.android.libraries.designsystem.components.dialogs.ConfirmationDialog +import io.element.android.libraries.designsystem.components.dialogs.SaveChangesDialog import io.element.android.libraries.designsystem.components.list.ListItemContent import io.element.android.libraries.designsystem.preview.ElementPreviewDark import io.element.android.libraries.designsystem.preview.ElementPreviewLight @@ -50,6 +53,7 @@ import io.element.android.libraries.designsystem.theme.components.TextButton import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableSet +import java.security.Security @Composable fun SecurityAndPrivacyView( @@ -57,12 +61,17 @@ fun SecurityAndPrivacyView( onBackClick: () -> Unit, modifier: Modifier = Modifier, ) { + BackHandler { + state.eventSink(SecurityAndPrivacyEvents.Exit) + } Scaffold( modifier = modifier, topBar = { SecurityAndPrivacyToolbar( isSaveActionEnabled = state.canBeSaved, - onBackClick = onBackClick, + onBackClick = { + state.eventSink(SecurityAndPrivacyEvents.Exit) + }, onSaveClick = { state.eventSink(SecurityAndPrivacyEvents.Save) }, @@ -131,6 +140,17 @@ fun SecurityAndPrivacyView( }, onRetry = { state.eventSink(SecurityAndPrivacyEvents.Save) }, ) + AsyncActionView( + async = state.confirmExitAction, + onSuccess = { onBackClick() }, + onErrorDismiss = { }, + confirmationDialog = { + SaveChangesDialog( + onSubmitClick = { state.eventSink(SecurityAndPrivacyEvents.Exit) }, + onDismiss = { state.eventSink(SecurityAndPrivacyEvents.DismissExitConfirmation) } + ) + }, + ) } @OptIn(ExperimentalMaterial3Api::class) From f775a599d8a40a0508e028a86582f17b7466156e Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 26 Nov 2025 15:16:13 +0100 Subject: [PATCH 072/113] quality: fix formatting and test --- .../impl/root/SecurityAndPrivacyEvents.kt | 2 +- .../impl/root/SecurityAndPrivacyPresenter.kt | 4 +- .../root/SecurityAndPrivacyStateProvider.kt | 2 +- .../impl/root/SecurityAndPrivacyView.kt | 3 +- .../impl/SecurityAndPrivacyViewTest.kt | 42 +++++++++++++++---- 5 files changed, 39 insertions(+), 14 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvents.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvents.kt index 2553090541..b1d739c45b 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvents.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyEvents.kt @@ -11,7 +11,7 @@ package io.element.android.features.securityandprivacy.impl.root sealed interface SecurityAndPrivacyEvents { data object EditRoomAddress : SecurityAndPrivacyEvents data object Save : SecurityAndPrivacyEvents - data object Exit: SecurityAndPrivacyEvents + data object Exit : SecurityAndPrivacyEvents data object DismissExitConfirmation : SecurityAndPrivacyEvents data class ChangeRoomAccess(val roomAccess: SecurityAndPrivacyRoomAccess) : SecurityAndPrivacyEvents data object ToggleEncryptionState : SecurityAndPrivacyEvents diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index 5bcbe15f7c..dd28ca65dd 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -21,9 +21,9 @@ import androidx.compose.runtime.setValue import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedFactory import dev.zacsweers.metro.AssistedInject +import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissionsAsState import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNavigator import io.element.android.features.securityandprivacy.impl.editroomaddress.matchesServer -import io.element.android.features.securityandprivacy.api.securityAndPrivacyPermissionsAsState import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.AsyncData.* @@ -65,7 +65,7 @@ class SecurityAndPrivacyPresenter( featureFlagService.isFeatureEnabledFlow(FeatureFlags.Knock) }.collectAsState(false) val saveAction = remember { mutableStateOf>(AsyncAction.Uninitialized) } - var confirmExitAction by remember { mutableStateOf>(AsyncAction.Uninitialized)} + var confirmExitAction by remember { mutableStateOf>(AsyncAction.Uninitialized) } val homeserverName = remember { matrixClient.userIdServerName() } val syncUpdateFlow = room.syncUpdateFlow.collectAsState() val roomInfo by room.roomInfoFlow.collectAsState() diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt index 00dc175b4c..11e5665c1c 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyStateProvider.kt @@ -117,7 +117,7 @@ fun aSecurityAndPrivacyState( canChangeRoomVisibility = true ), isKnockEnabled: Boolean = true, - isSpace: Boolean, + isSpace: Boolean = false, eventSink: (SecurityAndPrivacyEvents) -> Unit = {} ) = SecurityAndPrivacyState( editedSettings = editedSettings, diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index a4e3396f44..3ba4b8a142 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -218,7 +218,7 @@ private fun RoomAccessSection( ListItem( headlineContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_title)) }, supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_description)) }, - trailingContent = ListItemContent.RadioButton(selected = edited == SecurityAndPrivacyRoomAccess.SpaceMember, enabled = false), + trailingContent = ListItemContent.RadioButton(selected = edited == SecurityAndPrivacyRoomAccess.SpaceMember, enabled = false), leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Workspace())), enabled = false, ) @@ -243,7 +243,6 @@ private fun RoomAccessSection( leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Lock())), onClick = { onSelectOption(SecurityAndPrivacyRoomAccess.InviteOnly) }, ) - } } diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt index c7ab57a577..c4c004b265 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt @@ -21,12 +21,12 @@ import io.element.android.features.securityandprivacy.impl.root.SecurityAndPriva import io.element.android.features.securityandprivacy.impl.root.SecurityAndPrivacyView import io.element.android.features.securityandprivacy.impl.root.aSecurityAndPrivacySettings import io.element.android.features.securityandprivacy.impl.root.aSecurityAndPrivacyState +import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.tests.testutils.EnsureNeverCalled import io.element.android.tests.testutils.EventsRecorder import io.element.android.tests.testutils.clickOn -import io.element.android.tests.testutils.ensureCalledOnce import io.element.android.tests.testutils.pressBack import org.junit.Rule import org.junit.Test @@ -39,15 +39,41 @@ class SecurityAndPrivacyViewTest { @get:Rule val rule = createAndroidComposeRule() @Test - fun `click on back invokes expected callback`() { - ensureCalledOnce { callback -> - rule.setSecurityAndPrivacyView( - onBackClick = callback, - ) - rule.pressBack() - } + fun `click on back invokes emits the expected event`() { + val recorder = EventsRecorder() + val state = aSecurityAndPrivacyState( + eventSink = recorder, + ) + rule.setSecurityAndPrivacyView(state) + rule.pressBack() + recorder.assertSingle(SecurityAndPrivacyEvents.Exit) } + @Test + fun `confirm cancellation emits the expected event`() { + val recorder = EventsRecorder() + val state = aSecurityAndPrivacyState( + confirmExitAction = AsyncAction.ConfirmingCancellation, + eventSink = recorder, + ) + rule.setSecurityAndPrivacyView(state) + rule.clickOn(CommonStrings.action_ok) + recorder.assertSingle(SecurityAndPrivacyEvents.Exit) + } + + @Test + fun `dismiss cancellation confirmation emits the expected event`() { + val recorder = EventsRecorder() + val state = aSecurityAndPrivacyState( + confirmExitAction = AsyncAction.ConfirmingCancellation, + eventSink = recorder, + ) + rule.setSecurityAndPrivacyView(state) + rule.clickOn(CommonStrings.action_cancel) + recorder.assertSingle(SecurityAndPrivacyEvents.DismissExitConfirmation) + } + + @Test fun `click on room access item emits the expected event`() { val recorder = EventsRecorder() From 47d43c0a1919021d64b5f5549e108a61e8730df5 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 26 Nov 2025 15:06:32 +0000 Subject: [PATCH 073/113] fix(deps): update dependency org.matrix.rustcomponents:sdk-android to v25.11.26 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index c0bb446e87..108b4fde04 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -177,7 +177,7 @@ test_detekt_test = { module = "io.gitlab.arturbosch.detekt:detekt-test", version # https://github.com/matrix-org/matrix-rust-components-kotlin/commits/main/sdk/sdk-android/src/main/kotlin/org/matrix/rustcomponents/sdk/matrix_sdk_ffi.kt # All new features should not be implemented in the pull request that upgrades the version, developers should # only fix API breaks and may add some TODOs. -matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.11.24" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.11.26" # Others coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } From 1834d8000fb249d35b6103f3ab97d1a03fafb264 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Wed, 26 Nov 2025 15:10:07 +0000 Subject: [PATCH 074/113] Update screenshots --- ...impl.securityandprivacy_SecurityAndPrivacyViewDark_0_en.png | 3 --- ...impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en.png | 3 --- ...impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en.png | 3 --- ...impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en.png | 3 --- ...impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en.png | 3 --- ...impl.securityandprivacy_SecurityAndPrivacyViewDark_5_en.png | 3 --- ...impl.securityandprivacy_SecurityAndPrivacyViewDark_6_en.png | 3 --- ...impl.securityandprivacy_SecurityAndPrivacyViewDark_7_en.png | 3 --- ...impl.securityandprivacy_SecurityAndPrivacyViewDark_8_en.png | 3 --- ...impl.securityandprivacy_SecurityAndPrivacyViewDark_9_en.png | 3 --- ...mpl.securityandprivacy_SecurityAndPrivacyViewLight_0_en.png | 3 --- ...mpl.securityandprivacy_SecurityAndPrivacyViewLight_1_en.png | 3 --- ...mpl.securityandprivacy_SecurityAndPrivacyViewLight_2_en.png | 3 --- ...mpl.securityandprivacy_SecurityAndPrivacyViewLight_3_en.png | 3 --- ...mpl.securityandprivacy_SecurityAndPrivacyViewLight_4_en.png | 3 --- ...mpl.securityandprivacy_SecurityAndPrivacyViewLight_5_en.png | 3 --- ...mpl.securityandprivacy_SecurityAndPrivacyViewLight_6_en.png | 3 --- ...mpl.securityandprivacy_SecurityAndPrivacyViewLight_7_en.png | 3 --- ...mpl.securityandprivacy_SecurityAndPrivacyViewLight_8_en.png | 3 --- ...mpl.securityandprivacy_SecurityAndPrivacyViewLight_9_en.png | 3 --- ...vacy.impl.editroomaddress_EditRoomAddressView_Day_0_en.png} | 0 ...vacy.impl.editroomaddress_EditRoomAddressView_Day_1_en.png} | 0 ...vacy.impl.editroomaddress_EditRoomAddressView_Day_2_en.png} | 0 ...vacy.impl.editroomaddress_EditRoomAddressView_Day_3_en.png} | 0 ...vacy.impl.editroomaddress_EditRoomAddressView_Day_4_en.png} | 0 ...cy.impl.editroomaddress_EditRoomAddressView_Night_0_en.png} | 0 ...cy.impl.editroomaddress_EditRoomAddressView_Night_1_en.png} | 0 ...cy.impl.editroomaddress_EditRoomAddressView_Night_2_en.png} | 0 ...cy.impl.editroomaddress_EditRoomAddressView_Night_3_en.png} | 0 ...cy.impl.editroomaddress_EditRoomAddressView_Night_4_en.png} | 0 ...ityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png | 3 +++ ...ityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en.png | 3 +++ ...ityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en.png | 3 +++ ...ityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en.png | 3 +++ ...ityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png | 3 +++ ...ityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png | 3 +++ ...ityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png | 3 +++ ...ityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png | 3 +++ ...ityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en.png | 3 +++ ...ityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en.png | 3 +++ ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en.png | 3 +++ ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en.png | 3 +++ ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en.png | 3 +++ ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en.png | 3 +++ ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png | 3 +++ ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png | 3 +++ ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png | 3 +++ ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png | 3 +++ ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png | 3 +++ ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en.png | 3 +++ ...tyandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en.png | 3 +++ 70 files changed, 120 insertions(+), 60 deletions(-) delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_5_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_6_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_7_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_8_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_9_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_0_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_5_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_6_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_7_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_8_en.png delete mode 100644 tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_9_en.png rename tests/uitests/src/test/snapshots/images/{features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_0_en.png => features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_1_en.png => features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_2_en.png => features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_3_en.png => features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_4_en.png => features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_0_en.png => features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_1_en.png => features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_2_en.png => features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_3_en.png => features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en.png} (100%) rename tests/uitests/src/test/snapshots/images/{features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_4_en.png => features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en.png} (100%) create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_0_en.png deleted file mode 100644 index 8971f2f33c..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:54c924c8f8874050a874ba7cf46c2518c682c7bdb0987a5c3ce10a43b8faceb3 -size 36216 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en.png deleted file mode 100644 index 5ffb675c87..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b4701427ccafa8bb12a8f384433862770b84c650268772e11df91343c25bb1b0 -size 56924 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en.png deleted file mode 100644 index f227c74f10..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b307b024232c5033ab6aaf2930f244106fdb5a2bdd6c4919c24a60266fb4a814 -size 54885 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en.png deleted file mode 100644 index 08e6c8aad9..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:aad071d4ebb05c5db831bbf75021b7dcc9de185455c7f0292d3275247bcd5b75 -size 57403 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en.png deleted file mode 100644 index 474c7943ff..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:25c09f5b840f62fc4d71b15acefb6ad73f64df7ed6e7228d0cdfd16487f1e20e -size 57503 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_5_en.png deleted file mode 100644 index dabb4ac712..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_5_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2864979f28763dc975a79402d38f38cbbe52b0a9338847d8848cbf71b1423dfe -size 36089 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_6_en.png deleted file mode 100644 index dabb4ac712..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_6_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2864979f28763dc975a79402d38f38cbbe52b0a9338847d8848cbf71b1423dfe -size 36089 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_7_en.png deleted file mode 100644 index 31768159c1..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_7_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:cb41d1dd32d3812de94dca3236e83c35c54024a97402044d75e541476bb265a4 -size 41684 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_8_en.png deleted file mode 100644 index 014cfe0f8c..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_8_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ee12f0c2d1950347357914a3dcd69feafca46a6bcaa3de779493d1aa14fefa2b -size 31249 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_9_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_9_en.png deleted file mode 100644 index 1dc35b3b2b..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_9_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:53101722bdc3002df0d01827753d56cd0d47676396967b4c0d8b01fe9d048947 -size 56621 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_0_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_0_en.png deleted file mode 100644 index 4de3f3321f..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_0_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:ccb10ece709e70a13ce8ee8d4c37d4d4cc3ad3b17cf8697306cf5919877377b9 -size 37712 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_en.png deleted file mode 100644 index 43b341d174..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:6d3bc2a629aceda805d0976f46c6cf9ddca8ef05123fafe5d51500d68fea5c99 -size 58981 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_en.png deleted file mode 100644 index 2ae2618dac..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:518131a76d772d7b7eddbf74702e4a2a477dfea2ae9b89de58269d02820bfdca -size 56907 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_en.png deleted file mode 100644 index afbdc3a813..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:767c62fbb463557379dae310a4d830c0f86818ace934a25307ea3befe86042ac -size 59459 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_en.png deleted file mode 100644 index 52568b8670..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:b85a87cdb67b1ef8280d65e77abb77f6319a029a571a0747c4c56c2f4a652824 -size 59580 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_5_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_5_en.png deleted file mode 100644 index a03986e6ef..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_5_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2cbb5af6e3c4ee623911ac087257771a72e461777cc2485a09575e96d53e57e1 -size 37563 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_6_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_6_en.png deleted file mode 100644 index a03986e6ef..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_6_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:2cbb5af6e3c4ee623911ac087257771a72e461777cc2485a09575e96d53e57e1 -size 37563 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_7_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_7_en.png deleted file mode 100644 index 8751501f2f..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_7_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:3099335a1567dfde3a68d7af8c894f9bdd4c29882eccd3d4e3756450f15e50a9 -size 43759 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_8_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_8_en.png deleted file mode 100644 index cc45166325..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_8_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:4f6cddc09a2a9668af04a8da45dd6edd8c8cf6bfcf9b104f21dce91663940868 -size 32691 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_9_en.png b/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_9_en.png deleted file mode 100644 index 47ebe3a1fd..0000000000 --- a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_9_en.png +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:083a8f10725f4573807865f02b53ca0a3c6ff2bf43d99997afa9412a547c33bd -size 58652 diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_0_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_0_en.png rename to tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_1_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_1_en.png rename to tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_2_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_2_en.png rename to tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_3_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_3_en.png rename to tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_4_en.png rename to tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_0_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_0_en.png rename to tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_1_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_1_en.png rename to tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_2_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_2_en.png rename to tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_3_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_3_en.png rename to tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en.png similarity index 100% rename from tests/uitests/src/test/snapshots/images/features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_4_en.png rename to tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en.png new file mode 100644 index 0000000000..ae15fd2efd --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:59cfdfa8b68af10024d8650b680481a37b5717d981999adce49a0e62d55e433f +size 38619 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en.png new file mode 100644 index 0000000000..9ac055352b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b9c5983ff1143ef6c517dc948b9b60102607ff397748e8d87f3b565ab86efc4b +size 46360 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en.png new file mode 100644 index 0000000000..d5640cc559 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64d0aecdae4cd8c7581ded462d8534620cd006a78a089a4333c1608e8023ead1 +size 46768 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en.png new file mode 100644 index 0000000000..52e6f29adb --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:a4230969f15739f418eebe1d4a14e895c84bbe5bdbf832ccc60ae4bfafea0839 +size 19751 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en.png new file mode 100644 index 0000000000..6f9172af47 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4eb56b2db5b843d94f89c60baea02809d43733b718c59f0d06c1cee7ad4db9a7 +size 47036 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png new file mode 100644 index 0000000000..d5640cc559 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:64d0aecdae4cd8c7581ded462d8534620cd006a78a089a4333c1608e8023ead1 +size 46768 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png new file mode 100644 index 0000000000..f367faca6b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b3f5880e027ca7f380d24144efe8de3a222e359f5bf2e700f5af701dbe5d9bec +size 47145 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png new file mode 100644 index 0000000000..ef258a39e6 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e6895ffbb2c5b10705135ca748d7bfb243c19c250d5f9a5fa3cedf3f83baba0c +size 33097 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png new file mode 100644 index 0000000000..c883064bb0 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:2701337aad7fcdd419770718dc57c3ff6a1567cf23420624471a23120a3b9f8d +size 31593 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png new file mode 100644 index 0000000000..d24af812f5 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ced07a8e45e02c9fef27fa7bdbe969a26c73c850672d7b7167c58ff09cd9ed78 +size 32927 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png new file mode 100644 index 0000000000..a1c720f7c3 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f91b888b3948956f57a3d4a94ebea36e5da6c39d606170e3bb748e9caca70127 +size 41892 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en.png new file mode 100644 index 0000000000..5b752d5035 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f4bda58361cf1c8dd39d634203038ab7c8ac130df1aa465fb9dfb37a439b1c72 +size 59877 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en.png new file mode 100644 index 0000000000..22f6338462 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b3b390cabae48e7f5487737b89d2d9e7a18f538a4601a0b262fc205954ef70a3 +size 59439 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en.png new file mode 100644 index 0000000000..a28746d476 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1ec795cb5ffcb06e29be3a59dd95d88232f518bae66f96c05f1b75197cefdbf3 +size 59992 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png new file mode 100644 index 0000000000..2781d8a337 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:d213f421daa486febb24033e0d3928b47e6380e21889636d6b51550ee66b99b8 +size 36843 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png new file mode 100644 index 0000000000..1a79cae3e1 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c604f0a5f6003f51da4dadff3a01080b54ff2f2e34a4a4a9d2fbf0e5fac20221 +size 60117 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png new file mode 100644 index 0000000000..2393e0a15b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67e064c056d4559c3ab183015f47aed82360c0a9846170ec95f83089c22c22a2 +size 59864 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png new file mode 100644 index 0000000000..2dd0307a7a --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:ea71f66e3a2e1b3e513c806875d59088a33a4dedcd198b409ef3ec1c6bab59ed +size 60223 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en.png new file mode 100644 index 0000000000..1e97e4c8f2 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:db47cd993b12896c3439c7f4c9bddde833c5048a33f84b41aa15c48277cd53e9 +size 21577 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en.png new file mode 100644 index 0000000000..169f1ad8f9 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:83a1ff18c075d93b625ab55d2c54a767612b2af278ec6e5d1ebd9a509647c809 +size 46782 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en.png new file mode 100644 index 0000000000..41d20622ba --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:49bf2a919952035933e6d658076a845845f51fd33c2a3c21cc1f1e332ee95825 +size 40258 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en.png new file mode 100644 index 0000000000..ecced7e27f --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:808934308408e850551bc3103cee5a37d85d106adf567105003b0144651ca408 +size 47683 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en.png new file mode 100644 index 0000000000..e2a98e5f81 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bbf2bff6460019434e1af725763ef775240b832b947d7faea760ae08b31a1815 +size 48101 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en.png new file mode 100644 index 0000000000..59c10f26e9 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:7064846fe9af8d99fc1bf40ce410149a9b52cffab7b7d54b4383aace6689933e +size 20358 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en.png new file mode 100644 index 0000000000..ae17ccb1aa --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:805fdb8f857bdffe88caccd4f62bc1c2251a8119a51e865e3b7da9b9f6ff22b0 +size 48377 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png new file mode 100644 index 0000000000..e2a98e5f81 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:bbf2bff6460019434e1af725763ef775240b832b947d7faea760ae08b31a1815 +size 48101 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png new file mode 100644 index 0000000000..a17602cc6d --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:c121a184f66582bedf67ed73ec4740b3ce6984a264cfe04c241138bfa5d022a7 +size 48562 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png new file mode 100644 index 0000000000..c7b5337e1b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:11edb6109de15b857f90da338a0be8b5f1e202129fc3357ed3669ffc1edbf51a +size 34662 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png new file mode 100644 index 0000000000..a32249c2ad --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f55c84fb18a3a60b1621125edc305c6245f1bd042724198bf505ca1b7c39231c +size 33593 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png new file mode 100644 index 0000000000..1129971ac4 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:4d11da663b4512e76a74774da0b191dc4a72daa0edfcf68ab011469c73302ff0 +size 35017 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png new file mode 100644 index 0000000000..d68df083c4 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:398a2bb2ea12547edcc0af04fe85c83c4ea19aeb4e385d6e5b81b6a2eef96006 +size 44007 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en.png new file mode 100644 index 0000000000..9af2e30e19 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:618d2b08a9eaf0a7e56403125c785937e7078bff435bcc76ecafd068921d8f2a +size 61912 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en.png new file mode 100644 index 0000000000..11df3bd052 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:b3d9c431a14e527cad513fc92a5081b0b4dc6ae5153d381456684eb06b88e1fe +size 61491 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en.png new file mode 100644 index 0000000000..6e23df8b30 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:84aff9af3ac8512db3790f8c41cde10b0fcfdf29b7390ea48f460e4e21a3cbe4 +size 62146 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png new file mode 100644 index 0000000000..8c60403815 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:67467daa13b1a5d404686ddf94ea9a133f3546b43770b6d1e264782ae054f198 +size 38350 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png new file mode 100644 index 0000000000..40ccd4d4fe --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:0312b48791d6c0af66d25b01bc9f9f8f78dbf1808aafbf5251df3c6490e62e3a +size 62171 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png new file mode 100644 index 0000000000..b9a696d0d2 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e9b1fa55fd171af2eef1bd6cb874b0e542dd32332f56e21c430f3f7767d56d35 +size 61905 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png new file mode 100644 index 0000000000..69b7b4374b --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:958b45102cb3fcefd7461f86e1870ac44daf6c9f9b13583ba4f60106c20b6bab +size 62349 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en.png new file mode 100644 index 0000000000..7a45fa88bb --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:e37f1f6e15cee552219e997aa8dd491e672d73e55900f3e2cbdeea08f1355373 +size 22125 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en.png new file mode 100644 index 0000000000..63616838a9 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:aeff0b99f3ca35b84735ad464c78f4b69ca6ba22bdc67eb4ef56268d04bbb859 +size 48109 From 4af4944a557ab6a5b859bbcb98a2b8fb3a0d0ebd Mon Sep 17 00:00:00 2001 From: ganfra Date: Wed, 26 Nov 2025 17:03:27 +0100 Subject: [PATCH 075/113] deps: fix api break --- .../libraries/matrix/api/auth/qrlogin/QrLoginException.kt | 1 + .../android/libraries/matrix/impl/auth/qrlogin/QrErrorMapper.kt | 1 + 2 files changed, 2 insertions(+) diff --git a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/qrlogin/QrLoginException.kt b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/qrlogin/QrLoginException.kt index 4099e525cf..c81437eff0 100644 --- a/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/qrlogin/QrLoginException.kt +++ b/libraries/matrix/api/src/main/kotlin/io/element/android/libraries/matrix/api/auth/qrlogin/QrLoginException.kt @@ -20,4 +20,5 @@ sealed class QrLoginException : Exception() { data object CheckCodeAlreadySent : QrLoginException() data object CheckCodeCannotBeSent : QrLoginException() data object Unknown : QrLoginException() + data object NotFound : QrLoginException() } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/qrlogin/QrErrorMapper.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/qrlogin/QrErrorMapper.kt index 73875da558..65e15b5f2b 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/qrlogin/QrErrorMapper.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/auth/qrlogin/QrErrorMapper.kt @@ -45,5 +45,6 @@ object QrErrorMapper { is RustHumanQrLoginException.SlidingSyncNotAvailable -> QrLoginException.SlidingSyncNotAvailable is RustHumanQrLoginException.CheckCodeAlreadySent -> QrLoginException.CheckCodeAlreadySent is RustHumanQrLoginException.CheckCodeCannotBeSent -> QrLoginException.CheckCodeCannotBeSent + is RustHumanQrLoginException.NotFound -> QrLoginException.NotFound } } From f3d7b16463ea7b680076ea6175d9ab4965ff9ef6 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 26 Nov 2025 17:14:33 +0100 Subject: [PATCH 076/113] Fix crash when recording long voice message. --- .../composer/DefaultVoiceMessageComposerPresenter.kt | 5 ++++- .../element/android/libraries/textcomposer/TextComposer.kt | 5 ++++- .../libraries/textcomposer/components/LiveWaveformView.kt | 2 +- .../textcomposer/components/VoiceMessageRecording.kt | 2 +- 4 files changed, 10 insertions(+), 4 deletions(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenter.kt index 1acaae2aae..5405124283 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenter.kt @@ -192,7 +192,10 @@ class DefaultVoiceMessageComposerPresenter( voiceMessageState = when (val state = recorderState) { is VoiceRecorderState.Recording -> VoiceMessageState.Recording( duration = state.elapsedTime, - levels = state.levels.toImmutableList(), + levels = state.levels + // Keep only the last 128 samples for display, else we can have a crash + .takeLast(128) + .toImmutableList(), ) is VoiceRecorderState.Finished -> previewState( diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt index 5553fd0b01..f2070c9610 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/TextComposer.kt @@ -299,7 +299,10 @@ fun TextComposer( onSeek = onSeekVoiceMessage, ) is VoiceMessageState.Recording -> - VoiceMessageRecording(voiceMessageState.levels, voiceMessageState.duration) + VoiceMessageRecording( + levels = voiceMessageState.levels, + duration = voiceMessageState.duration, + ) VoiceMessageState.Idle -> {} } } diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/LiveWaveformView.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/LiveWaveformView.kt index 48d7dcdc3e..5e4ad02bd6 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/LiveWaveformView.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/LiveWaveformView.kt @@ -54,7 +54,7 @@ fun LiveWaveformView( var parentWidth by remember { mutableIntStateOf(0) } - val waveformWidth by remember(levels, lineWidth, linePadding) { + val waveformWidth by remember(levels.size, lineWidth, linePadding) { derivedStateOf { levels.size * (lineWidth.value + linePadding.value) } diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageRecording.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageRecording.kt index 17bdf3e7bf..e742372108 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageRecording.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/VoiceMessageRecording.kt @@ -74,7 +74,7 @@ internal fun VoiceMessageRecording( modifier = Modifier .height(26.dp) .weight(1f), - levels = levels + levels = levels, ) } } From a344b11eaa8a83dff79660a0981fedcc74008049 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Nov 2025 07:16:13 +0100 Subject: [PATCH 077/113] Rename test class --- ...enterTest.kt => DefaultVoiceMessageComposerPresenterTest.kt} | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) rename features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/{VoiceMessageComposerPresenterTest.kt => DefaultVoiceMessageComposerPresenterTest.kt} (99%) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/VoiceMessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenterTest.kt similarity index 99% rename from features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/VoiceMessageComposerPresenterTest.kt rename to features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenterTest.kt index 73688d2db4..c5ea1743a8 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/VoiceMessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenterTest.kt @@ -57,7 +57,7 @@ import java.io.File import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds -class VoiceMessageComposerPresenterTest { +class DefaultVoiceMessageComposerPresenterTest { @get:Rule val warmUpRule = WarmUpRule() From 0fbf15626210f0c6ee91dcabdfb6400974c08c8d Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Nov 2025 09:02:07 +0100 Subject: [PATCH 078/113] Use test extension --- ...efaultVoiceMessageComposerPresenterTest.kt | 96 +++++-------------- 1 file changed, 24 insertions(+), 72 deletions(-) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenterTest.kt index c5ea1743a8..ff98a65a70 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenterTest.kt @@ -12,10 +12,7 @@ package io.element.android.features.messages.impl.voicemessages.composer import android.Manifest import androidx.lifecycle.Lifecycle -import app.cash.molecule.RecompositionMode -import app.cash.molecule.moleculeFlow import app.cash.turbine.TurbineTestContext -import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import im.vector.app.features.analytics.plan.Composer import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerEvents @@ -46,6 +43,7 @@ import io.element.android.libraries.voicerecorder.test.FakeVoiceRecorder import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.lambda.lambdaRecorder +import io.element.android.tests.testutils.test import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.test.TestScope @@ -91,9 +89,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - initial state`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() assertThat(initialState.voiceMessageState).isEqualTo(VoiceMessageState.Idle) voiceRecorder.assertCalls(started = 0) @@ -105,9 +101,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - recording state`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) val finalState = awaitItem() @@ -121,9 +115,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - recording keeps screen on`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().apply { eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) assertThat(keepScreenOn).isFalse() @@ -145,9 +137,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - abort recording`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Cancel)) val finalState = awaitItem() @@ -160,9 +150,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - finish recording`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) @@ -177,9 +165,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - play recording before it is ready`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) val finalState = awaitItem().apply { this.eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Play)) @@ -196,9 +182,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - play recording`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) awaitItem().eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Play)) @@ -214,9 +198,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - pause recording`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) awaitItem().eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Play)) @@ -233,9 +215,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - seek recording`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) awaitItem().eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Seek(0.5f))) @@ -260,9 +240,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - delete recording`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) awaitItem().eventSink(VoiceMessageComposerEvents.DeleteVoiceMessage) @@ -278,9 +256,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - delete while playing`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) awaitItem().eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Play)) @@ -300,9 +276,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - send recording`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) awaitItem().eventSink(VoiceMessageComposerEvents.SendVoiceMessage) @@ -319,9 +293,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - sending is tracked`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { // Send a normal voice message messageComposerContext.composerMode = MessageComposerMode.Normal awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) @@ -348,9 +320,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - send while playing`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) awaitItem().eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Play)) @@ -370,9 +340,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - send recording before previous completed, waits`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) awaitItem().run { @@ -395,9 +363,7 @@ class DefaultVoiceMessageComposerPresenterTest { // Let sending fail due to media preprocessing error mediaPreProcessor.givenResult(Result.failure(Exception())) val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) awaitItem().apply { @@ -419,9 +385,7 @@ class DefaultVoiceMessageComposerPresenterTest { fun `present - send failures can be retried`() = runTest { // Let sending fail due to media preprocessing error val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { mediaPreProcessor.givenResult(Result.failure(Exception())) awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) @@ -448,9 +412,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - send failures are displayed as an error dialog`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { // Let sending fail due to media preprocessing error mediaPreProcessor.givenResult(Result.failure(Exception())) awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) @@ -483,9 +445,7 @@ class DefaultVoiceMessageComposerPresenterTest { @Test fun `present - send error - missing recording is tracked`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() // Send the message before recording anything initialState.eventSink(VoiceMessageComposerEvents.SendVoiceMessage) @@ -504,9 +464,7 @@ class DefaultVoiceMessageComposerPresenterTest { val exception = SecurityException("") voiceRecorder.givenThrowsSecurityException(exception) val presenter = createDefaultVoiceMessageComposerPresenter() - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) @@ -528,9 +486,7 @@ class DefaultVoiceMessageComposerPresenterTest { val presenter = createDefaultVoiceMessageComposerPresenter( permissionsPresenter = permissionsPresenter, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { val initialState = awaitItem() initialState.eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) assertThat(awaitItem().voiceMessageState).isEqualTo(VoiceMessageState.Idle) @@ -557,9 +513,7 @@ class DefaultVoiceMessageComposerPresenterTest { val presenter = createDefaultVoiceMessageComposerPresenter( permissionsPresenter = permissionsPresenter, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) // See the dialog and accept it @@ -591,9 +545,7 @@ class DefaultVoiceMessageComposerPresenterTest { val presenter = createDefaultVoiceMessageComposerPresenter( permissionsPresenter = permissionsPresenter, ) - moleculeFlow(RecompositionMode.Immediate) { - presenter.present() - }.test { + presenter.test { awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) // See the dialog and accept it From b25b99c890ddc6d3aee0b802938b46f4186ee44a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Nov 2025 09:24:43 +0100 Subject: [PATCH 079/113] Add unit test to ensure that number of levels is limited. --- ...efaultVoiceMessageComposerPresenterTest.kt | 26 +++++++++++++++++++ .../voicerecorder/test/FakeVoiceRecorder.kt | 2 ++ 2 files changed, 28 insertions(+) diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenterTest.kt index ff98a65a70..e478ccc726 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenterTest.kt @@ -39,6 +39,7 @@ import io.element.android.libraries.textcomposer.model.VoiceMessagePlayerEvent import io.element.android.libraries.textcomposer.model.VoiceMessageRecorderEvent import io.element.android.libraries.textcomposer.model.VoiceMessageState import io.element.android.libraries.voiceplayer.api.VoiceMessageException +import io.element.android.libraries.voicerecorder.api.VoiceRecorder import io.element.android.libraries.voicerecorder.test.FakeVoiceRecorder import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.WarmUpRule @@ -112,6 +113,30 @@ class DefaultVoiceMessageComposerPresenterTest { } } + @Test + fun `present - recording state - number of levels is limited`() = runTest { + val numberOfLevels = 200 + val levels = List(numberOfLevels) { it / numberOfLevels.toFloat() } + val voiceRecorder = FakeVoiceRecorder( + levels = levels, + recordingDuration = RECORDING_DURATION, + ) + val presenter = createDefaultVoiceMessageComposerPresenter( + voiceRecorder = voiceRecorder, + ) + presenter.test { + awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) + skipItems(numberOfLevels / 2 - 1) + val finalState = awaitItem() + assertThat(finalState.voiceMessageState).isInstanceOf(VoiceMessageState.Recording::class.java) + val recordingState = finalState.voiceMessageState as VoiceMessageState.Recording + // The number of levels should be limited to 128 items + assertThat(recordingState.levels.size).isEqualTo(128) + assertThat(recordingState.levels).isEqualTo(levels.takeLast(128)) + testPauseAndDestroy(finalState) + } + } + @Test fun `present - recording keeps screen on`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() @@ -614,6 +639,7 @@ class DefaultVoiceMessageComposerPresenterTest { private fun TestScope.createDefaultVoiceMessageComposerPresenter( permissionsPresenter: PermissionsPresenter = createFakePermissionsPresenter(), + voiceRecorder: VoiceRecorder = this@DefaultVoiceMessageComposerPresenterTest.voiceRecorder, ): DefaultVoiceMessageComposerPresenter { return DefaultVoiceMessageComposerPresenter( sessionCoroutineScope = backgroundScope, diff --git a/libraries/voicerecorder/test/src/main/kotlin/io/element/android/libraries/voicerecorder/test/FakeVoiceRecorder.kt b/libraries/voicerecorder/test/src/main/kotlin/io/element/android/libraries/voicerecorder/test/FakeVoiceRecorder.kt index a04f6d0ac9..ec62227857 100644 --- a/libraries/voicerecorder/test/src/main/kotlin/io/element/android/libraries/voicerecorder/test/FakeVoiceRecorder.kt +++ b/libraries/voicerecorder/test/src/main/kotlin/io/element/android/libraries/voicerecorder/test/FakeVoiceRecorder.kt @@ -14,6 +14,7 @@ import io.element.android.libraries.voicerecorder.api.VoiceRecorder import io.element.android.libraries.voicerecorder.api.VoiceRecorderState import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.StateFlow +import kotlinx.coroutines.yield import java.io.File import kotlin.time.Duration import kotlin.time.Duration.Companion.seconds @@ -49,6 +50,7 @@ class FakeVoiceRecorder( timeSource += recordingDuration for (i in 1..levels.size) { _state.emit(VoiceRecorderState.Recording(startedAt.elapsedNow(), levels.take(i))) + yield() } } From d94e8e7a2c64fdfa3c87f7e533c65526006a1cdf Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Nov 2025 09:41:29 +0100 Subject: [PATCH 080/113] Rename VoiceMessageComposerEvents to VoiceMessageComposerEvent --- ...Events.kt => VoiceMessageComposerEvent.kt} | 18 +-- .../composer/VoiceMessageComposerState.kt | 2 +- .../features/messages/impl/MessagesView.kt | 10 +- .../messagecomposer/MessageComposerView.kt | 10 +- .../DefaultVoiceMessageComposerPresenter.kt | 20 +-- ...efaultVoiceMessageComposerPresenterTest.kt | 140 +++++++++--------- 6 files changed, 100 insertions(+), 100 deletions(-) rename features/messages/api/src/main/kotlin/io/element/android/features/messages/api/timeline/voicemessages/composer/{VoiceMessageComposerEvents.kt => VoiceMessageComposerEvent.kt} (76%) diff --git a/features/messages/api/src/main/kotlin/io/element/android/features/messages/api/timeline/voicemessages/composer/VoiceMessageComposerEvents.kt b/features/messages/api/src/main/kotlin/io/element/android/features/messages/api/timeline/voicemessages/composer/VoiceMessageComposerEvent.kt similarity index 76% rename from features/messages/api/src/main/kotlin/io/element/android/features/messages/api/timeline/voicemessages/composer/VoiceMessageComposerEvents.kt rename to features/messages/api/src/main/kotlin/io/element/android/features/messages/api/timeline/voicemessages/composer/VoiceMessageComposerEvent.kt index 5220c4a762..ef5fe93d08 100644 --- a/features/messages/api/src/main/kotlin/io/element/android/features/messages/api/timeline/voicemessages/composer/VoiceMessageComposerEvents.kt +++ b/features/messages/api/src/main/kotlin/io/element/android/features/messages/api/timeline/voicemessages/composer/VoiceMessageComposerEvent.kt @@ -12,17 +12,17 @@ import androidx.lifecycle.Lifecycle import io.element.android.libraries.textcomposer.model.VoiceMessagePlayerEvent import io.element.android.libraries.textcomposer.model.VoiceMessageRecorderEvent -sealed interface VoiceMessageComposerEvents { +sealed interface VoiceMessageComposerEvent { data class RecorderEvent( val recorderEvent: VoiceMessageRecorderEvent - ) : VoiceMessageComposerEvents + ) : VoiceMessageComposerEvent data class PlayerEvent( val playerEvent: VoiceMessagePlayerEvent, - ) : VoiceMessageComposerEvents - data object SendVoiceMessage : VoiceMessageComposerEvents - data object DeleteVoiceMessage : VoiceMessageComposerEvents - data object AcceptPermissionRationale : VoiceMessageComposerEvents - data object DismissPermissionsRationale : VoiceMessageComposerEvents - data class LifecycleEvent(val event: Lifecycle.Event) : VoiceMessageComposerEvents - data object DismissSendFailureDialog : VoiceMessageComposerEvents + ) : VoiceMessageComposerEvent + data object SendVoiceMessage : VoiceMessageComposerEvent + data object DeleteVoiceMessage : VoiceMessageComposerEvent + data object AcceptPermissionRationale : VoiceMessageComposerEvent + data object DismissPermissionsRationale : VoiceMessageComposerEvent + data class LifecycleEvent(val event: Lifecycle.Event) : VoiceMessageComposerEvent + data object DismissSendFailureDialog : VoiceMessageComposerEvent } diff --git a/features/messages/api/src/main/kotlin/io/element/android/features/messages/api/timeline/voicemessages/composer/VoiceMessageComposerState.kt b/features/messages/api/src/main/kotlin/io/element/android/features/messages/api/timeline/voicemessages/composer/VoiceMessageComposerState.kt index 5a213cbbbb..f324bb7612 100644 --- a/features/messages/api/src/main/kotlin/io/element/android/features/messages/api/timeline/voicemessages/composer/VoiceMessageComposerState.kt +++ b/features/messages/api/src/main/kotlin/io/element/android/features/messages/api/timeline/voicemessages/composer/VoiceMessageComposerState.kt @@ -17,5 +17,5 @@ data class VoiceMessageComposerState( val showPermissionRationaleDialog: Boolean, val showSendFailureDialog: Boolean, val keepScreenOn: Boolean, - val eventSink: (VoiceMessageComposerEvents) -> Unit, + val eventSink: (VoiceMessageComposerEvent) -> Unit, ) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt index 1f62adeb23..03b04608d6 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesView.kt @@ -44,7 +44,7 @@ import androidx.compose.ui.text.style.TextAlign import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme -import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerEvents +import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerEvent import io.element.android.features.messages.impl.actionlist.ActionListEvents import io.element.android.features.messages.impl.actionlist.ActionListView import io.element.android.features.messages.impl.actionlist.model.TimelineItemAction @@ -120,7 +120,7 @@ fun MessagesView( knockRequestsBannerView: @Composable () -> Unit, ) { OnLifecycleEvent { _, event -> - state.voiceMessageComposerState.eventSink(VoiceMessageComposerEvents.LifecycleEvent(event)) + state.voiceMessageComposerState.eventSink(VoiceMessageComposerEvent.LifecycleEvent(event)) } KeepScreenOn(state.voiceMessageComposerState.keepScreenOn) @@ -399,17 +399,17 @@ private fun MessagesViewContent( if (state.voiceMessageComposerState.showPermissionRationaleDialog) { VoiceMessagePermissionRationaleDialog( onContinue = { - state.voiceMessageComposerState.eventSink(VoiceMessageComposerEvents.AcceptPermissionRationale) + state.voiceMessageComposerState.eventSink(VoiceMessageComposerEvent.AcceptPermissionRationale) }, onDismiss = { - state.voiceMessageComposerState.eventSink(VoiceMessageComposerEvents.DismissPermissionsRationale) + state.voiceMessageComposerState.eventSink(VoiceMessageComposerEvent.DismissPermissionsRationale) }, appName = state.appName ) } if (state.voiceMessageComposerState.showSendFailureDialog) { VoiceMessageSendingFailedDialog( - onDismiss = { state.voiceMessageComposerState.eventSink(VoiceMessageComposerEvents.DismissSendFailureDialog) }, + onDismiss = { state.voiceMessageComposerState.eventSink(VoiceMessageComposerEvent.DismissSendFailureDialog) }, ) } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt index 292a6b39a8..4b346e0c15 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/messagecomposer/MessageComposerView.kt @@ -18,7 +18,7 @@ import androidx.compose.ui.Modifier import androidx.compose.ui.platform.LocalView import androidx.compose.ui.tooling.preview.PreviewParameter import androidx.compose.ui.unit.dp -import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerEvents +import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerEvent import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerState import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerStateProvider import io.element.android.features.messages.api.timeline.voicemessages.composer.aVoiceMessageComposerState @@ -78,19 +78,19 @@ internal fun MessageComposerView( } val onVoiceRecorderEvent = { press: VoiceMessageRecorderEvent -> - voiceMessageState.eventSink(VoiceMessageComposerEvents.RecorderEvent(press)) + voiceMessageState.eventSink(VoiceMessageComposerEvent.RecorderEvent(press)) } val onSendVoiceMessage = { - voiceMessageState.eventSink(VoiceMessageComposerEvents.SendVoiceMessage) + voiceMessageState.eventSink(VoiceMessageComposerEvent.SendVoiceMessage) } val onDeleteVoiceMessage = { - voiceMessageState.eventSink(VoiceMessageComposerEvents.DeleteVoiceMessage) + voiceMessageState.eventSink(VoiceMessageComposerEvent.DeleteVoiceMessage) } val onVoicePlayerEvent = { event: VoiceMessagePlayerEvent -> - voiceMessageState.eventSink(VoiceMessageComposerEvents.PlayerEvent(event)) + voiceMessageState.eventSink(VoiceMessageComposerEvent.PlayerEvent(event)) } TextComposer( diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenter.kt index 5405124283..051ded02ae 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenter.kt @@ -26,7 +26,7 @@ import dev.zacsweers.metro.AssistedInject import dev.zacsweers.metro.ContributesBinding import im.vector.app.features.analytics.plan.Composer import io.element.android.features.messages.api.MessageComposerContext -import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerEvents +import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerEvent import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerPresenter import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerState import io.element.android.libraries.di.RoomScope @@ -164,25 +164,25 @@ class DefaultVoiceMessageComposerPresenter( } } - fun handleEvent(event: VoiceMessageComposerEvents) { + fun handleEvent(event: VoiceMessageComposerEvent) { when (event) { - is VoiceMessageComposerEvents.RecorderEvent -> handleVoiceMessageRecorderEvent(event.recorderEvent) - is VoiceMessageComposerEvents.PlayerEvent -> handleVoiceMessagePlayerEvent(event.playerEvent) - is VoiceMessageComposerEvents.SendVoiceMessage -> localCoroutineScope.launch { + is VoiceMessageComposerEvent.RecorderEvent -> handleVoiceMessageRecorderEvent(event.recorderEvent) + is VoiceMessageComposerEvent.PlayerEvent -> handleVoiceMessagePlayerEvent(event.playerEvent) + is VoiceMessageComposerEvent.SendVoiceMessage -> localCoroutineScope.launch { sendVoiceMessage() } - VoiceMessageComposerEvents.DeleteVoiceMessage -> { + VoiceMessageComposerEvent.DeleteVoiceMessage -> { player.pause() localCoroutineScope.deleteRecording() } - VoiceMessageComposerEvents.DismissPermissionsRationale -> { + VoiceMessageComposerEvent.DismissPermissionsRationale -> { permissionState.eventSink(PermissionsEvents.CloseDialog) } - VoiceMessageComposerEvents.AcceptPermissionRationale -> { + VoiceMessageComposerEvent.AcceptPermissionRationale -> { permissionState.eventSink(PermissionsEvents.OpenSystemSettingAndCloseDialog) } - is VoiceMessageComposerEvents.LifecycleEvent -> handleLifecycleEvent(event.event) - VoiceMessageComposerEvents.DismissSendFailureDialog -> { + is VoiceMessageComposerEvent.LifecycleEvent -> handleLifecycleEvent(event.event) + VoiceMessageComposerEvent.DismissSendFailureDialog -> { showSendFailureDialog = false } } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenterTest.kt index e478ccc726..48348f5e9a 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/voicemessages/composer/DefaultVoiceMessageComposerPresenterTest.kt @@ -15,7 +15,7 @@ import androidx.lifecycle.Lifecycle import app.cash.turbine.TurbineTestContext import com.google.common.truth.Truth.assertThat import im.vector.app.features.analytics.plan.Composer -import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerEvents +import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerEvent import io.element.android.features.messages.api.timeline.voicemessages.composer.VoiceMessageComposerState import io.element.android.features.messages.impl.messagecomposer.aReplyMode import io.element.android.features.messages.test.FakeMessageComposerContext @@ -103,7 +103,7 @@ class DefaultVoiceMessageComposerPresenterTest { fun `present - recording state`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) val finalState = awaitItem() assertThat(finalState.voiceMessageState).isEqualTo(RECORDING_STATE) @@ -125,7 +125,7 @@ class DefaultVoiceMessageComposerPresenterTest { voiceRecorder = voiceRecorder, ) presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) skipItems(numberOfLevels / 2 - 1) val finalState = awaitItem() assertThat(finalState.voiceMessageState).isInstanceOf(VoiceMessageState.Recording::class.java) @@ -142,13 +142,13 @@ class DefaultVoiceMessageComposerPresenterTest { val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { awaitItem().apply { - eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) + eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) assertThat(keepScreenOn).isFalse() } awaitItem().apply { assertThat(keepScreenOn).isTrue() - eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) } val finalState = awaitItem().apply { @@ -163,8 +163,8 @@ class DefaultVoiceMessageComposerPresenterTest { fun `present - abort recording`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Cancel)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Cancel)) val finalState = awaitItem() assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle) voiceRecorder.assertCalls(started = 1, stopped = 1, deleted = 1) @@ -176,8 +176,8 @@ class DefaultVoiceMessageComposerPresenterTest { fun `present - finish recording`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) val finalState = awaitItem() assertThat(finalState.voiceMessageState).isEqualTo(aPreviewState()) @@ -191,9 +191,9 @@ class DefaultVoiceMessageComposerPresenterTest { fun `present - play recording before it is ready`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) val finalState = awaitItem().apply { - this.eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Play)) + this.eventSink(VoiceMessageComposerEvent.PlayerEvent(VoiceMessagePlayerEvent.Play)) } // Nothing should happen @@ -208,9 +208,9 @@ class DefaultVoiceMessageComposerPresenterTest { fun `present - play recording`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) - awaitItem().eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Play)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + awaitItem().eventSink(VoiceMessageComposerEvent.PlayerEvent(VoiceMessagePlayerEvent.Play)) val finalState = awaitItem().also { assertThat(it.voiceMessageState).isEqualTo(aPlayingState()) } @@ -224,10 +224,10 @@ class DefaultVoiceMessageComposerPresenterTest { fun `present - pause recording`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) - awaitItem().eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Play)) - awaitItem().eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Pause)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + awaitItem().eventSink(VoiceMessageComposerEvent.PlayerEvent(VoiceMessagePlayerEvent.Play)) + awaitItem().eventSink(VoiceMessageComposerEvent.PlayerEvent(VoiceMessagePlayerEvent.Pause)) val finalState = awaitItem().also { assertThat(it.voiceMessageState).isEqualTo(aPausedState()) } @@ -241,15 +241,15 @@ class DefaultVoiceMessageComposerPresenterTest { fun `present - seek recording`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) - awaitItem().eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Seek(0.5f))) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + awaitItem().eventSink(VoiceMessageComposerEvent.PlayerEvent(VoiceMessagePlayerEvent.Seek(0.5f))) awaitItem().apply { assertThat(voiceMessageState).isEqualTo(aPreviewState(playbackProgress = 0.5f, time = 0.seconds, showCursor = true)) } awaitItem().apply { assertThat(voiceMessageState).isEqualTo(aPreviewState(playbackProgress = 0.5f, time = 5.seconds, showCursor = true)) - eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Seek(0.2f))) + eventSink(VoiceMessageComposerEvent.PlayerEvent(VoiceMessagePlayerEvent.Seek(0.2f))) } awaitItem().apply { assertThat(voiceMessageState).isEqualTo(aPreviewState(playbackProgress = 0.2f, time = 5.seconds, showCursor = true)) @@ -266,9 +266,9 @@ class DefaultVoiceMessageComposerPresenterTest { fun `present - delete recording`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) - awaitItem().eventSink(VoiceMessageComposerEvents.DeleteVoiceMessage) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + awaitItem().eventSink(VoiceMessageComposerEvent.DeleteVoiceMessage) val finalState = awaitItem() assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle) @@ -282,10 +282,10 @@ class DefaultVoiceMessageComposerPresenterTest { fun `present - delete while playing`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) - awaitItem().eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Play)) - awaitItem().eventSink(VoiceMessageComposerEvents.DeleteVoiceMessage) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + awaitItem().eventSink(VoiceMessageComposerEvent.PlayerEvent(VoiceMessagePlayerEvent.Play)) + awaitItem().eventSink(VoiceMessageComposerEvent.DeleteVoiceMessage) awaitItem().apply { assertThat(voiceMessageState).isEqualTo(aPausedState()) } @@ -302,9 +302,9 @@ class DefaultVoiceMessageComposerPresenterTest { fun `present - send recording`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) - awaitItem().eventSink(VoiceMessageComposerEvents.SendVoiceMessage) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + awaitItem().eventSink(VoiceMessageComposerEvent.SendVoiceMessage) assertThat(awaitItem().voiceMessageState).isEqualTo(aPreviewState().toSendingState()) val finalState = awaitItem() assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle) @@ -321,16 +321,16 @@ class DefaultVoiceMessageComposerPresenterTest { presenter.test { // Send a normal voice message messageComposerContext.composerMode = MessageComposerMode.Normal - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) - awaitItem().eventSink(VoiceMessageComposerEvents.SendVoiceMessage) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + awaitItem().eventSink(VoiceMessageComposerEvent.SendVoiceMessage) skipItems(1) // Sending state advanceUntilIdle() // Now reply with a voice message messageComposerContext.composerMode = aReplyMode() - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) - awaitItem().eventSink(VoiceMessageComposerEvents.SendVoiceMessage) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + awaitItem().eventSink(VoiceMessageComposerEvent.SendVoiceMessage) val finalState = awaitItem() // Sending state assertThat(analyticsService.capturedEvents).containsExactly( @@ -346,10 +346,10 @@ class DefaultVoiceMessageComposerPresenterTest { fun `present - send while playing`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) - awaitItem().eventSink(VoiceMessageComposerEvents.PlayerEvent(VoiceMessagePlayerEvent.Play)) - awaitItem().eventSink(VoiceMessageComposerEvents.SendVoiceMessage) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + awaitItem().eventSink(VoiceMessageComposerEvent.PlayerEvent(VoiceMessagePlayerEvent.Play)) + awaitItem().eventSink(VoiceMessageComposerEvent.SendVoiceMessage) assertThat(awaitItem().voiceMessageState).isEqualTo(aPlayingState().toSendingState()) skipItems(1) // Duplicate sending state @@ -366,11 +366,11 @@ class DefaultVoiceMessageComposerPresenterTest { fun `present - send recording before previous completed, waits`() = runTest { val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) awaitItem().run { - eventSink(VoiceMessageComposerEvents.SendVoiceMessage) - eventSink(VoiceMessageComposerEvents.SendVoiceMessage) + eventSink(VoiceMessageComposerEvent.SendVoiceMessage) + eventSink(VoiceMessageComposerEvent.SendVoiceMessage) } assertThat(awaitItem().voiceMessageState).isEqualTo(aPreviewState().toSendingState()) @@ -389,11 +389,11 @@ class DefaultVoiceMessageComposerPresenterTest { mediaPreProcessor.givenResult(Result.failure(Exception())) val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) awaitItem().apply { assertThat(voiceMessageState).isEqualTo(aPreviewState()) - eventSink(VoiceMessageComposerEvents.SendVoiceMessage) + eventSink(VoiceMessageComposerEvent.SendVoiceMessage) } val finalState = awaitItem() @@ -412,11 +412,11 @@ class DefaultVoiceMessageComposerPresenterTest { val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { mediaPreProcessor.givenResult(Result.failure(Exception())) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) val previewState = awaitItem() - previewState.eventSink(VoiceMessageComposerEvents.SendVoiceMessage) + previewState.eventSink(VoiceMessageComposerEvent.SendVoiceMessage) assertThat(awaitItem().voiceMessageState).isEqualTo(aPreviewState().toSendingState()) ensureAllEventsConsumed() @@ -424,7 +424,7 @@ class DefaultVoiceMessageComposerPresenterTest { sendVoiceMessageResult.assertions().isNeverCalled() mediaPreProcessor.givenAudioResult() - previewState.eventSink(VoiceMessageComposerEvents.SendVoiceMessage) + previewState.eventSink(VoiceMessageComposerEvent.SendVoiceMessage) val finalState = awaitItem() assertThat(finalState.voiceMessageState).isEqualTo(VoiceMessageState.Idle) sendVoiceMessageResult.assertions().isCalledOnce() @@ -440,9 +440,9 @@ class DefaultVoiceMessageComposerPresenterTest { presenter.test { // Let sending fail due to media preprocessing error mediaPreProcessor.givenResult(Result.failure(Exception())) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) - awaitItem().eventSink(VoiceMessageComposerEvents.SendVoiceMessage) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + awaitItem().eventSink(VoiceMessageComposerEvent.SendVoiceMessage) assertThat(awaitItem().voiceMessageState).isEqualTo(aPreviewState().toSendingState()) @@ -454,7 +454,7 @@ class DefaultVoiceMessageComposerPresenterTest { awaitItem().apply { assertThat(voiceMessageState).isEqualTo(aPreviewState()) assertThat(showSendFailureDialog).isTrue() - eventSink(VoiceMessageComposerEvents.DismissSendFailureDialog) + eventSink(VoiceMessageComposerEvent.DismissSendFailureDialog) } val finalState = awaitItem().apply { @@ -473,7 +473,7 @@ class DefaultVoiceMessageComposerPresenterTest { presenter.test { val initialState = awaitItem() // Send the message before recording anything - initialState.eventSink(VoiceMessageComposerEvents.SendVoiceMessage) + initialState.eventSink(VoiceMessageComposerEvent.SendVoiceMessage) assertThat(initialState.voiceMessageState).isEqualTo(VoiceMessageState.Idle) sendVoiceMessageResult.assertions().isNeverCalled() @@ -491,7 +491,7 @@ class DefaultVoiceMessageComposerPresenterTest { val presenter = createDefaultVoiceMessageComposerPresenter() presenter.test { val initialState = awaitItem() - initialState.eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) + initialState.eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) sendVoiceMessageResult.assertions().isNeverCalled() assertThat(analyticsService.trackedErrors).containsExactly( @@ -513,15 +513,15 @@ class DefaultVoiceMessageComposerPresenterTest { ) presenter.test { val initialState = awaitItem() - initialState.eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) + initialState.eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) assertThat(awaitItem().voiceMessageState).isEqualTo(VoiceMessageState.Idle) - initialState.eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Stop)) + initialState.eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Stop)) voiceRecorder.assertCalls(stopped = 1) permissionsPresenter.setPermissionGranted() - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) val finalState = awaitItem() assertThat(finalState.voiceMessageState).isEqualTo(RECORDING_STATE) voiceRecorder.assertCalls(stopped = 1, started = 1) @@ -539,13 +539,13 @@ class DefaultVoiceMessageComposerPresenterTest { permissionsPresenter = permissionsPresenter, ) presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) // See the dialog and accept it awaitItem().also { assertThat(it.voiceMessageState).isEqualTo(VoiceMessageState.Idle) assertThat(it.showPermissionRationaleDialog).isTrue() - it.eventSink(VoiceMessageComposerEvents.AcceptPermissionRationale) + it.eventSink(VoiceMessageComposerEvent.AcceptPermissionRationale) } // Dialog is hidden, user accepts permissions @@ -553,7 +553,7 @@ class DefaultVoiceMessageComposerPresenterTest { permissionsPresenter.setPermissionGranted() - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) val finalState = awaitItem() assertThat(finalState.voiceMessageState).isEqualTo(RECORDING_STATE) voiceRecorder.assertCalls(started = 1) @@ -571,19 +571,19 @@ class DefaultVoiceMessageComposerPresenterTest { permissionsPresenter = permissionsPresenter, ) presenter.test { - awaitItem().eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) + awaitItem().eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) // See the dialog and accept it awaitItem().also { assertThat(it.voiceMessageState).isEqualTo(VoiceMessageState.Idle) assertThat(it.showPermissionRationaleDialog).isTrue() - it.eventSink(VoiceMessageComposerEvents.DismissPermissionsRationale) + it.eventSink(VoiceMessageComposerEvent.DismissPermissionsRationale) } // Dialog is hidden, user tries to record again awaitItem().also { assertThat(it.showPermissionRationaleDialog).isFalse() - it.eventSink(VoiceMessageComposerEvents.RecorderEvent(VoiceMessageRecorderEvent.Start)) + it.eventSink(VoiceMessageComposerEvent.RecorderEvent(VoiceMessageRecorderEvent.Start)) } // Dialog is shown once again @@ -601,7 +601,7 @@ class DefaultVoiceMessageComposerPresenterTest { mostRecentState: VoiceMessageComposerState, ) { mostRecentState.eventSink( - VoiceMessageComposerEvents.LifecycleEvent(event = Lifecycle.Event.ON_PAUSE) + VoiceMessageComposerEvent.LifecycleEvent(event = Lifecycle.Event.ON_PAUSE) ) val onPauseState = when (val state = mostRecentState.voiceMessageState) { @@ -622,7 +622,7 @@ class DefaultVoiceMessageComposerPresenterTest { } onPauseState.eventSink( - VoiceMessageComposerEvents.LifecycleEvent(event = Lifecycle.Event.ON_DESTROY) + VoiceMessageComposerEvent.LifecycleEvent(event = Lifecycle.Event.ON_DESTROY) ) when (val state = onPauseState.voiceMessageState) { From 597a243579ba78f8f73b261daf243bd2545ab39a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Nov 2025 09:57:07 +0100 Subject: [PATCH 081/113] Inject RoomMemberListDataSource in the presenter constructor. --- .../rolesandpermissions/impl/roles/ChangeRolesPresenter.kt | 4 +--- .../impl/roles/ChangeRolesPresenterTest.kt | 3 ++- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt index f7736cb77c..88da850fcd 100644 --- a/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt +++ b/features/rolesandpermissions/impl/src/main/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenter.kt @@ -27,7 +27,6 @@ import io.element.android.features.rolesandpermissions.impl.RoomMemberListDataSo import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runUpdatingState -import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.designsystem.theme.components.SearchBarResultState import io.element.android.libraries.di.annotations.RoomCoroutineScope import io.element.android.libraries.matrix.api.core.UserId @@ -55,7 +54,7 @@ import kotlinx.coroutines.launch class ChangeRolesPresenter( @Assisted private val role: RoomMember.Role, private val room: JoinedRoom, - private val dispatchers: CoroutineDispatchers, + private val dataSource: RoomMemberListDataSource, private val analyticsService: AnalyticsService, @RoomCoroutineScope private val roomCoroutineScope: CoroutineScope, ) : Presenter { @@ -68,7 +67,6 @@ class ChangeRolesPresenter( @Composable override fun present(): ChangeRolesState { - val dataSource = remember { RoomMemberListDataSource(room, dispatchers) } var query by rememberSaveable { mutableStateOf(null) } var searchActive by rememberSaveable { mutableStateOf(false) } var searchResults by remember { diff --git a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt index 4bc39fd971..1da7ddcce4 100644 --- a/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt +++ b/features/rolesandpermissions/impl/src/test/kotlin/io/element/android/features/rolesandpermissions/impl/roles/ChangeRolesPresenterTest.kt @@ -10,6 +10,7 @@ package io.element.android.features.rolesandpermissions.impl.roles import com.google.common.truth.Truth.assertThat import im.vector.app.features.analytics.plan.RoomModeration +import io.element.android.features.rolesandpermissions.impl.RoomMemberListDataSource import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.core.coroutine.CoroutineDispatchers import io.element.android.libraries.designsystem.theme.components.SearchBarResultState @@ -576,7 +577,7 @@ internal fun TestScope.createChangeRolesPresenter( return ChangeRolesPresenter( role = role, room = room, - dispatchers = dispatchers, + dataSource = RoomMemberListDataSource(room, dispatchers), analyticsService = analyticsService, roomCoroutineScope = this, ) From 63e582f773316cf5dffc5dbad285631f2b7fb2c3 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Thu, 27 Nov 2025 10:34:34 +0100 Subject: [PATCH 082/113] fix(deps): update dependencyanalysis to v3.5.1 (#5819) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 108b4fde04..1a8ebd36a2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -49,7 +49,7 @@ telephoto = "0.18.0" haze = "1.6.10" # Dependency analysis -dependencyAnalysis = "3.5.0" +dependencyAnalysis = "3.5.1" # DI metro = "0.7.7" From 5624386f98499a0c65ce409188c42764b2fba753 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Nov 2025 12:22:57 +0100 Subject: [PATCH 083/113] Add indicators in room list for sending event and errors. --- .../home/impl/components/RoomSummaryRow.kt | 94 ++++++++++++++----- .../datasource/RoomListRoomSummaryFactory.kt | 28 +++++- .../features/home/impl/model/LatestEvent.kt | 34 +++++++ .../home/impl/model/RoomListRoomSummary.kt | 2 +- .../impl/model/RoomListRoomSummaryProvider.kt | 28 +++--- .../impl/roomlist/RoomListStateProvider.kt | 7 +- .../impl/model/RoomListBaseRoomSummaryTest.kt | 2 +- .../home/impl/roomlist/RoomListViewTest.kt | 6 +- .../src/main/res/values/localazy.xml | 1 + 9 files changed, 160 insertions(+), 42 deletions(-) create mode 100644 features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/LatestEvent.kt diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt index c43f7dcdd2..da0f47ba05 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/components/RoomSummaryRow.kt @@ -40,6 +40,7 @@ import androidx.compose.ui.zIndex import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.home.impl.R +import io.element.android.features.home.impl.model.LatestEvent import io.element.android.features.home.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.model.RoomListRoomSummaryProvider import io.element.android.features.home.impl.model.RoomSummaryDisplayType @@ -120,6 +121,7 @@ internal fun RoomSummaryRow( ) { NameAndTimestampRow( name = room.name, + latestEvent = room.latestEvent, timestamp = room.timestamp, isHighlighted = room.isHighlighted ) @@ -136,6 +138,7 @@ internal fun RoomSummaryRow( ) { NameAndTimestampRow( name = room.name, + latestEvent = room.latestEvent, timestamp = null, isHighlighted = room.isHighlighted ) @@ -211,6 +214,7 @@ private fun RoomSummaryScaffoldRow( @Composable private fun NameAndTimestampRow( name: String?, + latestEvent: LatestEvent, timestamp: String?, isHighlighted: Boolean, modifier: Modifier = Modifier @@ -219,16 +223,42 @@ private fun NameAndTimestampRow( modifier = modifier.fillMaxWidth(), horizontalArrangement = spacedBy(16.dp) ) { - // Name - Text( + Row( modifier = Modifier.weight(1f), - style = ElementTheme.typography.fontBodyLgMedium, - text = name ?: stringResource(id = CommonStrings.common_no_room_name), - fontStyle = FontStyle.Italic.takeIf { name == null }, - color = ElementTheme.colors.roomListRoomName, - maxLines = 1, - overflow = TextOverflow.Ellipsis - ) + verticalAlignment = Alignment.CenterVertically, + ) { + // Name + Text( + style = ElementTheme.typography.fontBodyLgMedium, + text = name ?: stringResource(id = CommonStrings.common_no_room_name), + fontStyle = FontStyle.Italic.takeIf { name == null }, + color = ElementTheme.colors.roomListRoomName, + maxLines = 1, + overflow = TextOverflow.Ellipsis + ) + // Picto + when (latestEvent) { + is LatestEvent.Sending -> { + Spacer(modifier = Modifier.width(4.dp)) + Icon( + modifier = Modifier.size(16.dp), + imageVector = CompoundIcons.Time(), + contentDescription = null, + tint = ElementTheme.colors.iconTertiary, + ) + } + is LatestEvent.Error -> { + Spacer(modifier = Modifier.width(4.dp)) + Icon( + modifier = Modifier.size(16.dp), + imageVector = CompoundIcons.ErrorSolid(), + contentDescription = null, + tint = ElementTheme.colors.iconCriticalPrimary, + ) + } + else -> Unit + } + } // Timestamp Text( text = timestamp ?: "", @@ -274,21 +304,41 @@ private fun MessagePreviewAndIndicatorRow( modifier = modifier.fillMaxWidth(), horizontalArrangement = spacedBy(28.dp) ) { - val messagePreview = if (room.isTombstoned) { - stringResource(R.string.screen_roomlist_tombstoned_room_description) + if (room.isTombstoned) { + Text( + modifier = Modifier.weight(1f), + text = stringResource(R.string.screen_roomlist_tombstoned_room_description), + color = ElementTheme.colors.roomListRoomMessage, + style = ElementTheme.typography.fontBodyMdRegular, + minLines = 2, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + ) } else { - room.latestEvent.orEmpty() + if (room.latestEvent is LatestEvent.Error) { + Text( + modifier = Modifier.weight(1f), + text = stringResource(CommonStrings.common_message_failed_to_send), + color = ElementTheme.colors.textCriticalPrimary, + style = ElementTheme.typography.fontBodyMdRegular, + minLines = 2, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + ) + } else { + val messagePreview = room.latestEvent.content() + val annotatedMessagePreview = messagePreview as? AnnotatedString ?: AnnotatedString(text = messagePreview.orEmpty().toString()) + Text( + modifier = Modifier.weight(1f), + text = annotatedMessagePreview, + color = ElementTheme.colors.roomListRoomMessage, + style = ElementTheme.typography.fontBodyMdRegular, + minLines = 2, + maxLines = 2, + overflow = TextOverflow.Ellipsis, + ) + } } - val annotatedMessagePreview = messagePreview as? AnnotatedString ?: AnnotatedString(text = messagePreview.toString()) - Text( - modifier = Modifier.weight(1f), - text = annotatedMessagePreview, - color = ElementTheme.colors.roomListRoomMessage, - style = ElementTheme.typography.fontBodyMdRegular, - minLines = 2, - maxLines = 2, - overflow = TextOverflow.Ellipsis - ) // Call and unread Row( diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt index 935410e572..14121516d6 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt @@ -9,6 +9,7 @@ package io.element.android.features.home.impl.datasource import dev.zacsweers.metro.Inject +import io.element.android.features.home.impl.model.LatestEvent import io.element.android.features.home.impl.model.RoomListRoomSummary import io.element.android.features.home.impl.model.RoomSummaryDisplayType import io.element.android.libraries.core.extensions.orEmpty @@ -18,6 +19,7 @@ import io.element.android.libraries.designsystem.components.avatar.AvatarSize import io.element.android.libraries.eventformatter.api.RoomLatestEventFormatter import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.isDm +import io.element.android.libraries.matrix.api.roomlist.LatestEventValue import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.libraries.matrix.ui.model.getAvatarData import io.element.android.libraries.matrix.ui.model.toInviteSender @@ -44,7 +46,7 @@ class RoomListRoomSummaryFactory( mode = DateFormatterMode.TimeOrDate, useRelative = true, ), - latestEvent = roomLatestEventFormatter.format(roomSummary.latestEvent, roomInfo.isDm).orEmpty(), + latestEvent = computeLatestEvent(roomSummary.latestEvent, roomInfo.isDm), avatarData = avatarData, userDefinedNotificationMode = roomInfo.userDefinedNotificationMode, hasRoomCall = roomInfo.hasRoomCall, @@ -71,4 +73,28 @@ class RoomListRoomSummaryFactory( isSpace = roomInfo.isSpace, ) } + + private fun computeLatestEvent(latestEvent: LatestEventValue, dm: Boolean): LatestEvent { + return when (latestEvent) { + is LatestEventValue.None -> { + LatestEvent.None + } + is LatestEventValue.Local -> { + if (latestEvent.isSending) { + val content = roomLatestEventFormatter.format(latestEvent, dm).orEmpty() + LatestEvent.Sending( + content = content, + ) + } else { + LatestEvent.Error + } + } + is LatestEventValue.Remote -> { + val content = roomLatestEventFormatter.format(latestEvent, dm).orEmpty() + LatestEvent.Regular( + content = content, + ) + } + } + } } diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/LatestEvent.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/LatestEvent.kt new file mode 100644 index 0000000000..6a268e8284 --- /dev/null +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/LatestEvent.kt @@ -0,0 +1,34 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.features.home.impl.model + +import androidx.compose.runtime.Immutable + +@Immutable +sealed interface LatestEvent { + data object None : LatestEvent + + data class Regular( + val content: CharSequence?, + ) : LatestEvent + + data class Sending( + val content: CharSequence?, + ) : LatestEvent + + data object Error : LatestEvent + + fun content(): CharSequence? { + return when (this) { + is None -> null + is Regular -> content + is Sending -> content + is Error -> null + } + } +} diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummary.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummary.kt index aa983baf56..a59e444455 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummary.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummary.kt @@ -29,7 +29,7 @@ data class RoomListRoomSummary( val numberOfUnreadNotifications: Long, val isMarkedUnread: Boolean, val timestamp: String?, - val latestEvent: CharSequence?, + val latestEvent: LatestEvent, val avatarData: AvatarData, val userDefinedNotificationMode: RoomNotificationMode?, val hasRoomCall: Boolean, diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt index e88d6d0972..65c70f98ed 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt @@ -25,12 +25,14 @@ open class RoomListRoomSummaryProvider : PreviewParameterProvider { name = "Room", numberOfUnreadMessages = 1, timestamp = "14:18", - lastMessage = "A very very very very long message which suites on two lines", + latestEvent = LatestEvent.Regular("A very very very very long message which suites on two lines"), avatarData = AvatarData("!id", "R", size = AvatarSize.RoomListItem), id = "!roomId:domain", ), @@ -96,7 +97,7 @@ internal fun aRoomListRoomSummaryList(): ImmutableList { name = "Room#2", numberOfUnreadMessages = 0, timestamp = "14:16", - lastMessage = "A short message", + latestEvent = LatestEvent.Regular("A short message"), avatarData = AvatarData("!id", "Z", size = AvatarSize.RoomListItem), id = "!roomId2:domain", ), @@ -119,7 +120,7 @@ internal fun generateRoomListRoomSummaryList( name = "Room#$index", numberOfUnreadMessages = 0, timestamp = "14:16", - lastMessage = "A message", + latestEvent = LatestEvent.Regular("A message"), avatarData = AvatarData("!id$index", "${(65 + index % 26).toChar()}", size = AvatarSize.RoomListItem), id = "!roomId$index:domain", ) diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt index cbf6c145ad..0a5350d086 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt @@ -96,7 +96,7 @@ internal fun createRoomListRoomSummary( numberOfUnreadNotifications = numberOfUnreadNotifications, isMarkedUnread = isMarkedUnread, timestamp = timestamp, - latestEvent = "", + latestEvent = LatestEvent.Regular(""), avatarData = AvatarData(id = A_ROOM_ID.value, name = A_ROOM_NAME, size = AvatarSize.RoomListItem), displayType = displayType, userDefinedNotificationMode = userDefinedNotificationMode, diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt index 7855180926..bb82d51a79 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListViewTest.kt @@ -170,7 +170,7 @@ class RoomListViewTest { // Remove automatic initial events eventsRecorder.clear() - rule.onNodeWithText(room0.latestEvent!!.toString()).performClick() + rule.onNodeWithText(room0.latestEvent.content().toString()).performClick() } eventsRecorder.assertEmpty() @@ -192,7 +192,7 @@ class RoomListViewTest { ) // Remove automatic initial events eventsRecorder.clear() - rule.onNodeWithText(room0.latestEvent!!.toString()) + rule.onNodeWithText(room0.latestEvent.content().toString()) .performClick() .performClick() } @@ -214,7 +214,7 @@ class RoomListViewTest { // Remove automatic initial events eventsRecorder.clear() - rule.onNodeWithText(room0.latestEvent!!.toString()).performTouchInput { longClick() } + rule.onNodeWithText(room0.latestEvent.content().toString()).performTouchInput { longClick() } eventsRecorder.assertSingle(RoomListEvents.ShowContextMenu(room0)) } diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index b1586a8d66..6bf57481d4 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -246,6 +246,7 @@ Reason: %1$s." "Message" "Message actions" + "Message failed to send" "Message layout" "Message removed" "Modern" From 919b577659aaf436853914946887d643f47facaa Mon Sep 17 00:00:00 2001 From: ElementBot Date: Thu, 27 Nov 2025 12:17:28 +0000 Subject: [PATCH 084/113] Update screenshots --- .../features.home.impl.components_RoomSummaryRow_Day_36_en.png | 3 +++ .../features.home.impl.components_RoomSummaryRow_Day_37_en.png | 3 +++ ...eatures.home.impl.components_RoomSummaryRow_Night_36_en.png | 3 +++ ...eatures.home.impl.components_RoomSummaryRow_Night_37_en.png | 3 +++ 4 files changed, 12 insertions(+) create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_36_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_37_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_36_en.png create mode 100644 tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_37_en.png diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_36_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_36_en.png new file mode 100644 index 0000000000..fb772998e4 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_36_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:761e963499f97f21b5c5b8b80e5d75092fbc4305371bcc413f595b503890d511 +size 13085 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_37_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_37_en.png new file mode 100644 index 0000000000..42db131266 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Day_37_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:de31aa3dbb9c9427189621d35022211220197de8ed8584f36801eb99d613f0b1 +size 13728 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_36_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_36_en.png new file mode 100644 index 0000000000..bb29aaa4b5 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_36_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:1f7327f29c9236b549d7f5037e3483e487a23902c5c30bd20a7a4bc0e6c13bec +size 13009 diff --git a/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_37_en.png b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_37_en.png new file mode 100644 index 0000000000..c8ce9b58a1 --- /dev/null +++ b/tests/uitests/src/test/snapshots/images/features.home.impl.components_RoomSummaryRow_Night_37_en.png @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:f92a70303d515a135eb87eac344dc4a974183da8773524a48f790b31a70338e8 +size 13528 From 699cf9647e9bb6644155e7a875bcfd90a90e5dc0 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Thu, 27 Nov 2025 14:55:19 +0100 Subject: [PATCH 085/113] Room list: enable latest event sorter. --- .../libraries/matrix/impl/roomlist/RoomListExtensions.kt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt index 94651dfd40..84e759040d 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListExtensions.kt @@ -66,7 +66,11 @@ internal fun RoomListInterface.entriesFlow( trySendBlocking(roomEntriesUpdate) } } - val result = entriesWithDynamicAdapters(pageSize.toUInt(), listener) + val result = entriesWithDynamicAdaptersWith( + pageSize = pageSize.toUInt(), + enableLatestEventSorter = true, + listener = listener, + ) val controller = result.controller() controller.setFilter(initialFilterKind) roomListDynamicEvents.onEach { controllerEvents -> From 5d61504f2482542632f42376eb6774a567ed3ceb Mon Sep 17 00:00:00 2001 From: ganfra Date: Thu, 27 Nov 2025 19:02:15 +0100 Subject: [PATCH 086/113] quality: fix lint issues --- .../impl/root/SecurityAndPrivacyPresenter.kt | 3 +-- .../securityandprivacy/impl/root/SecurityAndPrivacyView.kt | 3 --- .../securityandprivacy/impl/SecurityAndPrivacyViewTest.kt | 1 - 3 files changed, 1 insertion(+), 6 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt index dd28ca65dd..43d8383b76 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyPresenter.kt @@ -26,7 +26,6 @@ import io.element.android.features.securityandprivacy.impl.SecurityAndPrivacyNav import io.element.android.features.securityandprivacy.impl.editroomaddress.matchesServer import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData -import io.element.android.libraries.architecture.AsyncData.* import io.element.android.libraries.architecture.Presenter import io.element.android.libraries.architecture.runCatchingUpdatingState import io.element.android.libraries.architecture.runUpdatingState @@ -135,7 +134,7 @@ class SecurityAndPrivacyPresenter( } SecurityAndPrivacyEvents.ToggleRoomVisibility -> { editedVisibleInRoomDirectory = when (val edited = editedVisibleInRoomDirectory) { - is Success -> Success(!edited.data) + is AsyncData.Success -> AsyncData.Success(!edited.data) else -> edited } } diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index 3ba4b8a142..32674ef34f 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -32,7 +32,6 @@ import androidx.compose.ui.unit.dp import io.element.android.compound.theme.ElementTheme import io.element.android.compound.tokens.generated.CompoundIcons import io.element.android.features.securityandprivacy.impl.R -import io.element.android.libraries.architecture.AsyncAction import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.coverage.ExcludeFromCoverage import io.element.android.libraries.designsystem.components.async.AsyncActionView @@ -53,8 +52,6 @@ import io.element.android.libraries.designsystem.theme.components.TextButton import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableSet -import java.security.Security - @Composable fun SecurityAndPrivacyView( state: SecurityAndPrivacyState, diff --git a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt index c4c004b265..78b840d823 100644 --- a/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt +++ b/features/securityandprivacy/impl/src/test/kotlin/io/element/android/features/securityandprivacy/impl/SecurityAndPrivacyViewTest.kt @@ -73,7 +73,6 @@ class SecurityAndPrivacyViewTest { recorder.assertSingle(SecurityAndPrivacyEvents.DismissExitConfirmation) } - @Test fun `click on room access item emits the expected event`() { val recorder = EventsRecorder() From 3d590c1c46a1e02fd2c33099fddcf2e98633fd99 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 19 Nov 2025 17:24:35 +0100 Subject: [PATCH 087/113] Have long running analytic transactions return actual transactions. Also add `AnalyticsService.getLongRunningTransaction` and change `AnalyticsService.stopLongRunningTransaction` to `removeLongRunningTransaction`. --- .../matrix/impl/roomlist/RoomListFactory.kt | 2 +- .../services/analytics/api/AnalyticsService.kt | 15 +++++++++++++-- .../analytics/impl/DefaultAnalyticsService.kt | 14 ++++++++++---- .../analytics/noop/NoopAnalyticsService.kt | 5 +++-- .../analytics/test/FakeAnalyticsService.kt | 15 +++++++++++++-- 5 files changed, 40 insertions(+), 11 deletions(-) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt index 4e342f3a48..1fd0871019 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt @@ -73,7 +73,7 @@ internal class RoomListFactory( initialFilterKind = RoomListEntriesDynamicFilterKind.All(ROOM_LIST_RUST_FILTERS), ).onEach { update -> if (!firstRoomsTransaction.isFinished()) { - analyticsService.stopLongRunningTransaction(AnalyticsLongRunningTransaction.FirstRoomsDisplayed) + analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.FirstRoomsDisplayed)?.finish() firstRoomsTransaction.finish() } processor.postUpdate(update) diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt index a936f47be1..726ec4180d 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt @@ -55,9 +55,20 @@ interface AnalyticsService : AnalyticsTracker, ErrorTracker { */ fun startTransaction(name: String, operation: String? = null): AnalyticsTransaction - fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction) + /** + * Starts an [AnalyticsLongRunningTransaction], that can be shared with other components. + */ + fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction - fun stopLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction) + /** + * Gets an ongoing [AnalyticsLongRunningTransaction], if it exists. + */ + fun getLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? + + /** + * Removes an ongoing [AnalyticsLongRunningTransaction] so it's no longer shared. + */ + fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? } inline fun AnalyticsService.recordTransaction(name: String, operation: String, block: (AnalyticsTransaction) -> T): T { diff --git a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt index e773212f33..83c76dc2fe 100644 --- a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt @@ -153,11 +153,17 @@ class DefaultAnalyticsService( } ?: NoopAnalyticsTransaction } - override fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction) { - pendingLongRunningTransactions[longRunningTransaction] = startTransaction(longRunningTransaction.name, longRunningTransaction.operation) + override fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction { + val transaction = startTransaction(longRunningTransaction.name, longRunningTransaction.operation) + pendingLongRunningTransactions[longRunningTransaction] = transaction + return transaction } - override fun stopLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction) { - pendingLongRunningTransactions.remove(longRunningTransaction)?.finish() + override fun getLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? { + return pendingLongRunningTransactions[longRunningTransaction] + } + + override fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? { + return pendingLongRunningTransactions.remove(longRunningTransaction) } } diff --git a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt index a2175231a4..36eeaa0aa2 100644 --- a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt +++ b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt @@ -39,6 +39,7 @@ class NoopAnalyticsService : AnalyticsService { override fun trackError(throwable: Throwable) = Unit override fun updateSuperProperties(updatedProperties: SuperProperties) = Unit override fun startTransaction(name: String, operation: String?): AnalyticsTransaction = NoopAnalyticsTransaction - override fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction) {} - override fun stopLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction) {} + override fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction = NoopAnalyticsTransaction + override fun getLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? = null + override fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction) = NoopAnalyticsTransaction } diff --git a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt index c83e0119ed..9899ced193 100644 --- a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt +++ b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt @@ -31,6 +31,7 @@ class FakeAnalyticsService( val screenEvents = mutableListOf() val trackedErrors = mutableListOf() val capturedUserProperties = mutableListOf() + val longRunningTransactions = mutableMapOf() override fun getAvailableAnalyticsProviders(): Set = emptySet() @@ -70,6 +71,16 @@ class FakeAnalyticsService( } override fun startTransaction(name: String, operation: String?): AnalyticsTransaction = NoopAnalyticsTransaction - override fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction) {} - override fun stopLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction) {} + override fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction { + longRunningTransactions[longRunningTransaction] = NoopAnalyticsTransaction + return NoopAnalyticsTransaction + } + + override fun getLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? { + return longRunningTransactions[longRunningTransaction] + } + + override fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? { + return longRunningTransactions.remove(longRunningTransaction) + } } From 8815fe79864f2e52372fc1532e78541e1075b0c6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 19 Nov 2025 17:27:56 +0100 Subject: [PATCH 088/113] Add a 'warm' room list performance check: We want to measure how long it takes the SDK to update the room list when the app comes back from being in background. Note we don't want to check this in cold starts, only warm ones. --- .../android/appnav/LoggedInFlowNode.kt | 4 + .../AnalyticsRoomListStateWatcher.kt | 79 ++++++++ .../AnalyticsRoomListStateWatcherTest.kt | 170 ++++++++++++++++++ .../api/AnalyticsLongRunningTransaction.kt | 1 + 4 files changed, 254 insertions(+) create mode 100644 appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcher.kt create mode 100644 appnav/src/test/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcherTest.kt diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index 5d0f373c11..310913e0ac 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -41,6 +41,7 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import im.vector.app.features.analytics.plan.JoinedRoom import io.element.android.annotations.ContributesNode +import io.element.android.appnav.analytics.AnalyticsRoomListStateWatcher import io.element.android.appnav.loggedin.LoggedInNode import io.element.android.appnav.loggedin.MediaPreviewConfigMigration import io.element.android.appnav.loggedin.SendQueues @@ -139,6 +140,7 @@ class LoggedInFlowNode( private val buildMeta: BuildMeta, snackbarDispatcher: SnackbarDispatcher, private val analyticsService: AnalyticsService, + private val analyticsRoomListStateWatcher: AnalyticsRoomListStateWatcher, ) : BaseFlowNode( backstack = BackStack( initialElement = NavTarget.Placeholder, @@ -202,6 +204,7 @@ class LoggedInFlowNode( } lifecycle.subscribe( onCreate = { + analyticsRoomListStateWatcher.start() appNavigationStateService.onNavigateToSession(id, matrixClient.sessionId) // TODO We do not support Space yet, so directly navigate to main space appNavigationStateService.onNavigateToSpace(id, MAIN_SPACE) @@ -238,6 +241,7 @@ class LoggedInFlowNode( appNavigationStateService.onLeavingSession(id) loggedInFlowProcessor.stopObserving() matrixClient.sessionVerificationService.setListener(null) + analyticsRoomListStateWatcher.stop() } ) setupSendingQueue() diff --git a/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcher.kt b/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcher.kt new file mode 100644 index 0000000000..91efa0bf92 --- /dev/null +++ b/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcher.kt @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.appnav.analytics + +import dev.zacsweers.metro.Inject +import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.core.coroutine.withPreviousValue +import io.element.android.libraries.di.annotations.SessionCoroutineScope +import io.element.android.libraries.matrix.api.roomlist.RoomListService +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.ResumeAppUntilNewRoomsReceived +import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.appnavstate.api.AppNavigationStateService +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.cancel +import kotlinx.coroutines.flow.distinctUntilChanged +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.onEach +import timber.log.Timber +import java.util.concurrent.atomic.AtomicBoolean + +/** + * This component is used to check how long it takes for the room list to be up to date after opening the app while it's on a 'warm' state: + * the app was previously running and we just returned to it. + */ +@Inject +class AnalyticsRoomListStateWatcher( + private val appNavigationStateService: AppNavigationStateService, + private val roomListService: RoomListService, + private val analyticsService: AnalyticsService, + @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, + private val dispatchers: CoroutineDispatchers, +) { + private var currentCoroutineScope: CoroutineScope? = null + private val isWarmState = AtomicBoolean(false) + + fun start() { + if (currentCoroutineScope != null) { + Timber.w("Can't start RoomListStateWatcher, it's already running.") + return + } + + val coroutineScope = CoroutineScope(sessionCoroutineScope.coroutineContext + dispatchers.computation) + appNavigationStateService.appNavigationState + .map { it.isInForeground } + .distinctUntilChanged() + .withPreviousValue() + .onEach { (wasInForeground, isInForeground) -> + if (isInForeground && roomListService.state.value != RoomListService.State.Running) { + analyticsService.startLongRunningTransaction(ResumeAppUntilNewRoomsReceived) + } + + if (wasInForeground == false && isInForeground) { + isWarmState.set(true) + } + } + .launchIn(coroutineScope) + + roomListService.state + .onEach { state -> + if (state == RoomListService.State.Running && isWarmState.get()) { + analyticsService.removeLongRunningTransaction(ResumeAppUntilNewRoomsReceived)?.finish() + } + } + .launchIn(coroutineScope) + + currentCoroutineScope = coroutineScope + } + + fun stop() { + currentCoroutineScope?.cancel() + currentCoroutineScope = null + } +} diff --git a/appnav/src/test/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcherTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcherTest.kt new file mode 100644 index 0000000000..f05190acc7 --- /dev/null +++ b/appnav/src/test/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcherTest.kt @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.appnav.analytics + +import com.google.common.truth.Truth.assertThat +import io.element.android.libraries.matrix.api.roomlist.RoomListService +import io.element.android.libraries.matrix.test.roomlist.FakeRoomListService +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.ResumeAppUntilNewRoomsReceived +import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.services.appnavstate.api.AppNavigationState +import io.element.android.services.appnavstate.api.NavigationState +import io.element.android.services.appnavstate.test.FakeAppNavigationStateService +import io.element.android.tests.testutils.testCoroutineDispatchers +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Test + +@OptIn(ExperimentalCoroutinesApi::class) +class AnalyticsRoomListStateWatcherTest { + @Test + fun `Opening the app in a warm state tracks the time until the room list is synced`() = runTest { + val navigationStateService = FakeAppNavigationStateService() + val roomListService = FakeRoomListService().apply { + postState(RoomListService.State.Idle) + } + val analyticsService = FakeAnalyticsService() + val watcher = createAnalyticsRoomListStateWatcher( + appNavigationStateService = navigationStateService, + roomListService = roomListService, + analyticsService = analyticsService, + ) + + watcher.start() + + // Give some time to load the initial state + runCurrent() + + // Make sure it's warm by changing its internal state + navigationStateService.appNavigationState.emit(AppNavigationState(navigationState = NavigationState.Root, isInForeground = false)) + runCurrent() + navigationStateService.appNavigationState.emit(AppNavigationState(navigationState = NavigationState.Root, isInForeground = true)) + runCurrent() + + // The transaction should be present now + assertThat(analyticsService.getLongRunningTransaction(ResumeAppUntilNewRoomsReceived)).isNotNull() + + // And now the room list service running + roomListService.postState(RoomListService.State.Running) + runCurrent() + + // And the transaction should now be gone + assertThat(analyticsService.getLongRunningTransaction(ResumeAppUntilNewRoomsReceived)).isNull() + + watcher.stop() + } + + @Test + fun `Opening the app in a cold state does nothing`() = runTest { + val navigationStateService = FakeAppNavigationStateService().apply { + appNavigationState.emit(AppNavigationState(NavigationState.Root, false)) + } + val roomListService = FakeRoomListService().apply { + postState(RoomListService.State.Idle) + } + val analyticsService = FakeAnalyticsService() + val watcher = createAnalyticsRoomListStateWatcher( + appNavigationStateService = navigationStateService, + roomListService = roomListService, + analyticsService = analyticsService, + ) + + watcher.start() + + // Give some time to load the initial state + runCurrent() + + // The room list service running + roomListService.postState(RoomListService.State.Running) + runCurrent() + + // The transaction was never present + assertThat(analyticsService.getLongRunningTransaction(ResumeAppUntilNewRoomsReceived)).isNull() + + watcher.stop() + } + + @Test + fun `The transaction won't be finished until the room list is synchronised`() = runTest { + val navigationStateService = FakeAppNavigationStateService() + val roomListService = FakeRoomListService().apply { + postState(RoomListService.State.Idle) + } + val analyticsService = FakeAnalyticsService() + val watcher = createAnalyticsRoomListStateWatcher( + appNavigationStateService = navigationStateService, + roomListService = roomListService, + analyticsService = analyticsService, + ) + + watcher.start() + + // Give some time to load the initial state + runCurrent() + + // Make sure it's warm by changing its internal state + navigationStateService.appNavigationState.emit(AppNavigationState(navigationState = NavigationState.Root, isInForeground = false)) + runCurrent() + navigationStateService.appNavigationState.emit(AppNavigationState(navigationState = NavigationState.Root, isInForeground = true)) + runCurrent() + + // The transaction should be present now + assertThat(analyticsService.getLongRunningTransaction(ResumeAppUntilNewRoomsReceived)).isNotNull() + + runCurrent() + + // But without the room list syncing, it never finishes + assertThat(analyticsService.getLongRunningTransaction(ResumeAppUntilNewRoomsReceived)).isNotNull() + + watcher.stop() + } + + @Test + fun `Opening the app when the room list state was already Running does nothing`() = runTest { + val navigationStateService = FakeAppNavigationStateService() + val roomListService = FakeRoomListService().apply { + postState(RoomListService.State.Running) + } + val analyticsService = FakeAnalyticsService() + val watcher = createAnalyticsRoomListStateWatcher( + appNavigationStateService = navigationStateService, + roomListService = roomListService, + analyticsService = analyticsService, + ) + + watcher.start() + + // Give some time to load the initial state + runCurrent() + + // Make sure it's warm by changing its internal state + navigationStateService.appNavigationState.emit(AppNavigationState(navigationState = NavigationState.Root, isInForeground = false)) + runCurrent() + navigationStateService.appNavigationState.emit(AppNavigationState(navigationState = NavigationState.Root, isInForeground = true)) + runCurrent() + + // The transaction was never added + assertThat(analyticsService.getLongRunningTransaction(ResumeAppUntilNewRoomsReceived)).isNull() + + watcher.stop() + } + + private fun TestScope.createAnalyticsRoomListStateWatcher( + appNavigationStateService: FakeAppNavigationStateService = FakeAppNavigationStateService(), + roomListService: FakeRoomListService = FakeRoomListService(), + analyticsService: FakeAnalyticsService = FakeAnalyticsService(), + ) = AnalyticsRoomListStateWatcher( + appNavigationStateService = appNavigationStateService, + roomListService = roomListService, + analyticsService = analyticsService, + sessionCoroutineScope = backgroundScope, + dispatchers = testCoroutineDispatchers(), + ) +} diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt index e465e2450a..c4aa5cc69b 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt @@ -12,4 +12,5 @@ sealed class AnalyticsLongRunningTransaction( val operation: String?, ) { data object FirstRoomsDisplayed : AnalyticsLongRunningTransaction("First rooms displayed after login or restoration", null) + data object ResumeAppUntilNewRoomsReceived : AnalyticsLongRunningTransaction("App was resumed and new room list items arrived", null) } From e1bd189ba06e0eba30cd4d2078f8e83af9db4401 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 20 Nov 2025 09:04:36 +0100 Subject: [PATCH 089/113] Add a performance check for notification tap -> populated timeline time --- .../element/android/x/intent/DefaultIntentProvider.kt | 1 + .../kotlin/io/element/android/appnav/RootFlowNode.kt | 10 +++++++++- .../messages/impl/timeline/TimelinePresenter.kt | 4 ++++ .../messages/impl/timeline/TimelinePresenterTest.kt | 2 ++ .../analytics/api/AnalyticsLongRunningTransaction.kt | 1 + 5 files changed, 17 insertions(+), 1 deletion(-) diff --git a/app/src/main/kotlin/io/element/android/x/intent/DefaultIntentProvider.kt b/app/src/main/kotlin/io/element/android/x/intent/DefaultIntentProvider.kt index 204ee27313..a4272063ba 100644 --- a/app/src/main/kotlin/io/element/android/x/intent/DefaultIntentProvider.kt +++ b/app/src/main/kotlin/io/element/android/x/intent/DefaultIntentProvider.kt @@ -36,6 +36,7 @@ class DefaultIntentProvider( return Intent(context, MainActivity::class.java).apply { action = Intent.ACTION_VIEW data = deepLinkCreator.create(sessionId, roomId, threadId, eventId).toUri() + putExtra("from_notification", true) } } } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt index 1a23bce132..6fce57926b 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt @@ -62,6 +62,8 @@ import io.element.android.libraries.oidc.api.OidcActionFlow import io.element.android.libraries.sessionstorage.api.LoggedInState import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.libraries.ui.common.nodes.emptyNode +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction +import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -86,6 +88,7 @@ class RootFlowNode( private val oidcActionFlow: OidcActionFlow, private val featureFlagService: FeatureFlagService, private val announcementService: AnnouncementService, + private val analyticsService: AnalyticsService, ) : BaseFlowNode( backstack = BackStack( initialElement = NavTarget.SplashScreen, @@ -310,7 +313,12 @@ class RootFlowNode( suspend fun handleIntent(intent: Intent) { val resolvedIntent = intentResolver.resolve(intent) ?: return when (resolvedIntent) { - is ResolvedIntent.Navigation -> navigateTo(resolvedIntent.deeplinkData) + is ResolvedIntent.Navigation -> { + if (intent.getBooleanExtra("from_notification", false) && resolvedIntent.deeplinkData is DeeplinkData.Room) { + analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.NotificationTapOpensTimeline) + } + navigateTo(resolvedIntent.deeplinkData) + } is ResolvedIntent.Login -> onLoginLink(resolvedIntent.params) is ResolvedIntent.Oidc -> onOidcAction(resolvedIntent.oidcAction) is ResolvedIntent.Permalink -> navigateTo(resolvedIntent.permalinkData) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt index 596c1d87e4..14b873491b 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt @@ -55,6 +55,8 @@ import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin import io.element.android.libraries.matrix.ui.room.canSendMessageAsState import io.element.android.libraries.preferences.api.store.SessionPreferencesStore +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction +import io.element.android.services.analytics.api.AnalyticsService import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.CoroutineScope @@ -86,6 +88,7 @@ class TimelinePresenter( private val typingNotificationPresenter: Presenter, private val roomCallStatePresenter: Presenter, private val featureFlagService: FeatureFlagService, + private val analyticsService: AnalyticsService, ) : Presenter { private val tag = "TimelinePresenter" @AssistedFactory @@ -225,6 +228,7 @@ class TimelinePresenter( LaunchedEffect(Unit) { timelineItemsFactory.timelineItems .onEach { newTimelineItems -> + analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.NotificationTapOpensTimeline)?.finish() timelineItemIndexer.process(newTimelineItems) timelineItems = newTimelineItems } diff --git a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt index fbfce752ea..13c28da6e9 100644 --- a/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt +++ b/features/messages/impl/src/test/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenterTest.kt @@ -60,6 +60,7 @@ import io.element.android.libraries.matrix.test.timeline.aMessageContent import io.element.android.libraries.matrix.test.timeline.anEventTimelineItem import io.element.android.libraries.matrix.ui.components.aMatrixUserList import io.element.android.libraries.preferences.test.InMemorySessionPreferencesStore +import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.awaitLastSequentialItem import io.element.android.tests.testutils.consumeItemsUntilPredicate @@ -1054,6 +1055,7 @@ class TimelinePresenterTest { typingNotificationPresenter = { aTypingNotificationState() }, roomCallStatePresenter = { aStandByCallState() }, featureFlagService = featureFlagService, + analyticsService = FakeAnalyticsService(), ) } } diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt index c4aa5cc69b..96dfe4ba3c 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt @@ -13,4 +13,5 @@ sealed class AnalyticsLongRunningTransaction( ) { data object FirstRoomsDisplayed : AnalyticsLongRunningTransaction("First rooms displayed after login or restoration", null) data object ResumeAppUntilNewRoomsReceived : AnalyticsLongRunningTransaction("App was resumed and new room list items arrived", null) + data object NotificationTapOpensTimeline : AnalyticsLongRunningTransaction("A notification was tapped and it opened a timeline", null) } From daf7bea39e76d3a3826beb985bf5217b939ad1bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 20 Nov 2025 10:08:53 +0100 Subject: [PATCH 090/113] Add another performance check for cold start time until the cached room list is displayed --- .../android/appnav/NotLoggedInFlowNode.kt | 3 + .../io/element/android/appnav/RootFlowNode.kt | 3 + .../analytics/AnalyticsColdStartWatcher.kt | 69 +++++++++++++++++++ features/home/impl/build.gradle.kts | 1 + .../home/impl/roomlist/RoomListPresenter.kt | 4 ++ .../impl/roomlist/RoomListPresenterTest.kt | 10 +++ .../api/AnalyticsLongRunningTransaction.kt | 1 + 7 files changed, 91 insertions(+) create mode 100644 appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt diff --git a/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt index d888ac3b15..b1d371b4c0 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt @@ -24,6 +24,7 @@ import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode +import io.element.android.appnav.analytics.AnalyticsColdStartWatcher import io.element.android.features.login.api.LoginEntryPoint import io.element.android.features.login.api.LoginParams import io.element.android.libraries.architecture.BackstackView @@ -43,6 +44,7 @@ class NotLoggedInFlowNode( @Assisted plugins: List, private val loginEntryPoint: LoginEntryPoint, private val imageLoaderHolder: ImageLoaderHolder, + private val analyticsColdStartWatcher: AnalyticsColdStartWatcher, ) : BaseFlowNode( backstack = BackStack( initialElement = NavTarget.Root, @@ -65,6 +67,7 @@ class NotLoggedInFlowNode( override fun onBuilt() { super.onBuilt() + analyticsColdStartWatcher.whenLoggingIn() lifecycle.subscribe( onResume = { SingletonImageLoader.setUnsafe(imageLoaderHolder.get()) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt index 6fce57926b..52788fc992 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt @@ -29,6 +29,7 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import im.vector.app.features.analytics.plan.JoinedRoom import io.element.android.annotations.ContributesNode +import io.element.android.appnav.analytics.AnalyticsColdStartWatcher import io.element.android.appnav.di.MatrixSessionCache import io.element.android.appnav.intent.IntentResolver import io.element.android.appnav.intent.ResolvedIntent @@ -89,6 +90,7 @@ class RootFlowNode( private val featureFlagService: FeatureFlagService, private val announcementService: AnnouncementService, private val analyticsService: AnalyticsService, + private val analyticsColdStartWatcher: AnalyticsColdStartWatcher, ) : BaseFlowNode( backstack = BackStack( initialElement = NavTarget.SplashScreen, @@ -98,6 +100,7 @@ class RootFlowNode( plugins = plugins ) { override fun onBuilt() { + analyticsColdStartWatcher.start() matrixSessionCache.restoreWithSavedState(buildContext.savedStateMap) super.onBuilt() observeNavState() diff --git a/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt b/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt new file mode 100644 index 0000000000..29dcd61211 --- /dev/null +++ b/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.appnav.analytics + +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.ContributesBinding +import dev.zacsweers.metro.SingleIn +import io.element.android.libraries.di.annotations.AppCoroutineScope +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction +import io.element.android.services.analytics.api.AnalyticsService +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.catch +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import timber.log.Timber +import java.util.concurrent.atomic.AtomicBoolean + +/** + * Adds a performance check transaction measuring the time between a cold start (or, after we read the user consent after a cold start) + * until the cached room list is displayed. This check only takes place in a cold app start after the user is authenticated. + */ +interface AnalyticsColdStartWatcher { + fun start() + fun whenLoggingIn() + fun onRoomListVisible() +} + +@SingleIn(AppScope::class) +@ContributesBinding(AppScope::class) +class DefaultAnalyticsColdStartWatcher( + private val analyticsService: AnalyticsService, + @AppCoroutineScope private val appCoroutineScope: CoroutineScope, +) : AnalyticsColdStartWatcher { + private val isColdStart = AtomicBoolean(true) + + override fun start() { + analyticsService.userConsentFlow + .onEach { hasConsent -> + if (hasConsent) { + if (isColdStart.get()) { + Timber.d("Starting cold start check") + analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList) + } else { + error("The app is no longer in a cold start state") + } + } + } + .catch { Timber.w(it.message) } + .launchIn(appCoroutineScope) + } + + override fun whenLoggingIn() { + if (isColdStart.getAndSet(false)) { + Timber.d("Canceled cold start check: user is logging in") + } + } + + override fun onRoomListVisible() { + if (isColdStart.getAndSet(false)) { + Timber.d("Room list is visible, finishing cold start check") + analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList)?.finish() + } + } +} diff --git a/features/home/impl/build.gradle.kts b/features/home/impl/build.gradle.kts index b36ee6aed2..9362702a1a 100644 --- a/features/home/impl/build.gradle.kts +++ b/features/home/impl/build.gradle.kts @@ -28,6 +28,7 @@ setupDependencyInjection() dependencies { implementation(projects.appconfig) + implementation(projects.appnav) implementation(projects.libraries.core) implementation(projects.libraries.androidutils) implementation(projects.libraries.architecture) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt index 6493d76d98..ce1197f9ca 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt @@ -25,6 +25,7 @@ import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import dev.zacsweers.metro.Inject import im.vector.app.features.analytics.plan.Interaction +import io.element.android.appnav.analytics.AnalyticsColdStartWatcher import io.element.android.features.announcement.api.Announcement import io.element.android.features.announcement.api.AnnouncementService import io.element.android.features.home.impl.datasource.RoomListDataSource @@ -86,6 +87,7 @@ class RoomListPresenter( private val appPreferencesStore: AppPreferencesStore, private val seenInvitesStore: SeenInvitesStore, private val announcementService: AnnouncementService, + private val coldStartWatcher: AnalyticsColdStartWatcher, ) : Presenter { private val encryptionService = client.encryptionService @@ -236,6 +238,8 @@ class RoomListPresenter( ) showSkeleton -> RoomListContentState.Skeleton(count = 16) else -> { + coldStartWatcher.onRoomListVisible() + RoomListContentState.Rooms( securityBannerState = securityBannerState, showNewNotificationSoundBanner = showNewNotificationSoundBanner, diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt index cf636e26ca..a3be896f40 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt @@ -13,6 +13,7 @@ import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import im.vector.app.features.analytics.plan.Interaction +import io.element.android.appnav.analytics.AnalyticsColdStartWatcher import io.element.android.features.announcement.api.Announcement import io.element.android.features.announcement.api.AnnouncementService import io.element.android.features.home.impl.FakeDateTimeObserver @@ -673,5 +674,14 @@ class RoomListPresenterTest { appPreferencesStore = appPreferencesStore, seenInvitesStore = seenInvitesStore, announcementService = announcementService, + coldStartWatcher = FakeAnalyticsColdStartWatcher(), ) } + +private class FakeAnalyticsColdStartWatcher : AnalyticsColdStartWatcher { + override fun start() {} + + override fun whenLoggingIn() {} + + override fun onRoomListVisible() {} +} diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt index 96dfe4ba3c..670b9ef268 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt @@ -11,6 +11,7 @@ sealed class AnalyticsLongRunningTransaction( val name: String, val operation: String?, ) { + data object ColdStartUntilCachedRoomList : AnalyticsLongRunningTransaction("Cold start until cached room list is displayed", null) data object FirstRoomsDisplayed : AnalyticsLongRunningTransaction("First rooms displayed after login or restoration", null) data object ResumeAppUntilNewRoomsReceived : AnalyticsLongRunningTransaction("App was resumed and new room list items arrived", null) data object NotificationTapOpensTimeline : AnalyticsLongRunningTransaction("A notification was tapped and it opened a timeline", null) From 10b31e3e7267e4e2f03ba79de33152c6ef22c26f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 20 Nov 2025 11:21:34 +0100 Subject: [PATCH 091/113] Add `OpenRoom` long running analytic transaction --- .../kotlin/io/element/android/appnav/room/RoomFlowNode.kt | 4 ++++ .../features/messages/impl/timeline/TimelinePresenter.kt | 1 + .../services/analytics/api/AnalyticsLongRunningTransaction.kt | 1 + 3 files changed, 6 insertions(+) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt index 22e1d925c9..16bae8c30f 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt @@ -48,6 +48,8 @@ import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias import io.element.android.libraries.matrix.ui.room.LoadingRoomState +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction +import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.filter @@ -70,6 +72,7 @@ class RoomFlowNode( private val joinRoomEntryPoint: JoinRoomEntryPoint, private val roomAliasResolverEntryPoint: RoomAliasResolverEntryPoint, private val membershipObserver: RoomMembershipObserver, + private val analyticsService: AnalyticsService, ) : BaseFlowNode( backstack = BackStack( initialElement = NavTarget.Loading, @@ -108,6 +111,7 @@ class RoomFlowNode( override fun onBuilt() { super.onBuilt() + analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.OpenRoom) resolveRoomId() } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt index 14b873491b..15ceb70682 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt @@ -229,6 +229,7 @@ class TimelinePresenter( timelineItemsFactory.timelineItems .onEach { newTimelineItems -> analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.NotificationTapOpensTimeline)?.finish() + analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.OpenRoom)?.finish() timelineItemIndexer.process(newTimelineItems) timelineItems = newTimelineItems } diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt index 670b9ef268..b173b2cb8f 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt @@ -15,4 +15,5 @@ sealed class AnalyticsLongRunningTransaction( data object FirstRoomsDisplayed : AnalyticsLongRunningTransaction("First rooms displayed after login or restoration", null) data object ResumeAppUntilNewRoomsReceived : AnalyticsLongRunningTransaction("App was resumed and new room list items arrived", null) data object NotificationTapOpensTimeline : AnalyticsLongRunningTransaction("A notification was tapped and it opened a timeline", null) + data object OpenRoom : AnalyticsLongRunningTransaction("Open a room and see loaded items in the timeline", null) } From 4b3796844fed3837d20be8b5980b3f231a59954e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 20 Nov 2025 12:23:03 +0100 Subject: [PATCH 092/113] Add transaction trees for opening a room so we can have a nice trace view --- .../analytics/AnalyticsColdStartWatcher.kt | 6 ++++-- .../android/appnav/room/RoomFlowNode.kt | 8 +++++-- .../room/joined/JoinedRoomLoadedFlowNode.kt | 8 +++++++ .../appnav/JoinedRoomLoadedFlowNodeTest.kt | 2 ++ .../features/messages/impl/MessagesNode.kt | 4 ++++ .../impl/timeline/TimelinePresenter.kt | 21 ++++++++++++++++--- .../matrix/impl/room/RustRoomFactory.kt | 8 ++++++- .../api/AnalyticsLongRunningTransaction.kt | 3 +++ .../analytics/api/AnalyticsService.kt | 15 ++++++++++--- .../analytics/impl/DefaultAnalyticsService.kt | 9 ++++++-- .../analytics/noop/NoopAnalyticsService.kt | 5 ++++- .../analytics/test/FakeAnalyticsService.kt | 5 ++++- .../sentry/SentryAnalyticsTransaction.kt | 8 ++++++- 13 files changed, 86 insertions(+), 16 deletions(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt b/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt index 29dcd61211..0782973cc4 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt @@ -12,6 +12,7 @@ import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.SingleIn import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.catch @@ -44,7 +45,7 @@ class DefaultAnalyticsColdStartWatcher( if (hasConsent) { if (isColdStart.get()) { Timber.d("Starting cold start check") - analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList) + analyticsService.startLongRunningTransaction(ColdStartUntilCachedRoomList) } else { error("The app is no longer in a cold start state") } @@ -56,6 +57,7 @@ class DefaultAnalyticsColdStartWatcher( override fun whenLoggingIn() { if (isColdStart.getAndSet(false)) { + analyticsService.removeLongRunningTransaction(ColdStartUntilCachedRoomList) Timber.d("Canceled cold start check: user is logging in") } } @@ -63,7 +65,7 @@ class DefaultAnalyticsColdStartWatcher( override fun onRoomListVisible() { if (isColdStart.getAndSet(false)) { Timber.d("Room list is visible, finishing cold start check") - analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList)?.finish() + analyticsService.removeLongRunningTransaction(ColdStartUntilCachedRoomList)?.finish() } } } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt index 16bae8c30f..9aa62d6b16 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt @@ -48,7 +48,9 @@ import io.element.android.libraries.matrix.api.room.CurrentUserMembership import io.element.android.libraries.matrix.api.room.RoomMembershipObserver import io.element.android.libraries.matrix.api.room.alias.ResolvedRoomAlias import io.element.android.libraries.matrix.ui.room.LoadingRoomState -import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.LoadJoinedRoomFlow +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.NotificationTapOpensTimeline +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.OpenRoom import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.distinctUntilChanged @@ -111,7 +113,9 @@ class RoomFlowNode( override fun onBuilt() { super.onBuilt() - analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.OpenRoom) + val parentTransaction = analyticsService.getLongRunningTransaction(NotificationTapOpensTimeline) + val openRoomTransaction = analyticsService.startLongRunningTransaction(OpenRoom, parentTransaction) + analyticsService.startLongRunningTransaction(LoadJoinedRoomFlow, openRoomTransaction) resolveRoomId() } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt index dab636031f..3ff8e16b49 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt @@ -45,6 +45,10 @@ import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.permalink.PermalinkData import io.element.android.libraries.matrix.api.room.JoinedRoom +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.LoadJoinedRoomFlow +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.LoadMessagesUi +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.OpenRoom +import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.appnavstate.api.ActiveRoomsHolder import io.element.android.services.appnavstate.api.AppNavigationStateService import kotlinx.coroutines.CoroutineScope @@ -66,6 +70,7 @@ class JoinedRoomLoadedFlowNode( private val sessionCoroutineScope: CoroutineScope, private val matrixClient: MatrixClient, private val activeRoomsHolder: ActiveRoomsHolder, + private val analyticsService: AnalyticsService, roomGraphFactory: RoomGraphFactory, ) : BaseFlowNode( backstack = BackStack( @@ -93,6 +98,8 @@ class JoinedRoomLoadedFlowNode( init { lifecycle.subscribe( onCreate = { + val parent = analyticsService.getLongRunningTransaction(OpenRoom) + analyticsService.startLongRunningTransaction(LoadMessagesUi, parent) Timber.v("OnCreate => ${inputs.room.roomId}") appNavigationStateService.onNavigateToRoom(id, inputs.room.roomId) activeRoomsHolder.addRoom(inputs.room) @@ -100,6 +107,7 @@ class JoinedRoomLoadedFlowNode( trackVisitedRoom() }, onResume = { + analyticsService.removeLongRunningTransaction(LoadJoinedRoomFlow)?.finish() sessionCoroutineScope.launch { inputs.room.subscribeToSync() } diff --git a/appnav/src/test/kotlin/io/element/android/appnav/JoinedRoomLoadedFlowNodeTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/JoinedRoomLoadedFlowNodeTest.kt index 77fcbae14e..6cd7df025b 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/JoinedRoomLoadedFlowNodeTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/JoinedRoomLoadedFlowNodeTest.kt @@ -34,6 +34,7 @@ import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.libraries.matrix.test.room.FakeBaseRoom import io.element.android.libraries.matrix.test.room.FakeJoinedRoom import io.element.android.libraries.matrix.test.room.aRoomInfo +import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.services.appnavstate.api.ActiveRoomsHolder import io.element.android.services.appnavstate.impl.DefaultActiveRoomsHolder import io.element.android.services.appnavstate.test.FakeAppNavigationStateService @@ -123,6 +124,7 @@ class JoinedRoomLoadedFlowNodeTest { roomGraphFactory = FakeRoomGraphFactory(), matrixClient = matrixClient, activeRoomsHolder = activeRoomsHolder, + analyticsService = FakeAnalyticsService(), ) @Test diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt index 168a4d6b3d..2032d70d64 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt @@ -68,6 +68,7 @@ import io.element.android.libraries.matrix.api.timeline.Timeline import io.element.android.libraries.matrix.api.timeline.item.TimelineItemDebugInfo import io.element.android.libraries.mediaplayer.api.MediaPlayer import io.element.android.libraries.ui.strings.CommonStrings +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.LoadMessagesUi import io.element.android.services.analytics.api.AnalyticsService import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList @@ -136,6 +137,9 @@ class MessagesNode( onCreate = { sessionCoroutineScope.launch { analyticsService.capture(room.toAnalyticsViewRoom()) } }, + onResume = { + analyticsService.removeLongRunningTransaction(LoadMessagesUi)?.finish() + }, onDestroy = { mediaPlayer.close() } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt index 15ceb70682..3044822256 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt @@ -55,7 +55,9 @@ import io.element.android.libraries.matrix.api.timeline.item.event.MessageShield import io.element.android.libraries.matrix.api.timeline.item.event.TimelineItemEventOrigin import io.element.android.libraries.matrix.ui.room.canSendMessageAsState import io.element.android.libraries.preferences.api.store.SessionPreferencesStore -import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.DisplayFirstTimelineItems +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.NotificationTapOpensTimeline +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.OpenRoom import io.element.android.services.analytics.api.AnalyticsService import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf @@ -111,6 +113,11 @@ class TimelinePresenter( @Composable override fun present(): TimelineState { + LaunchedEffect(Unit) { + val parent = analyticsService.getLongRunningTransaction(OpenRoom) + analyticsService.startLongRunningTransaction(DisplayFirstTimelineItems, parent) + } + val localScope = rememberCoroutineScope() val timelineMode = remember { timelineController.mainTimelineMode() } @@ -228,18 +235,26 @@ class TimelinePresenter( LaunchedEffect(Unit) { timelineItemsFactory.timelineItems .onEach { newTimelineItems -> - analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.NotificationTapOpensTimeline)?.finish() - analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.OpenRoom)?.finish() timelineItemIndexer.process(newTimelineItems) timelineItems = newTimelineItems + + analyticsService.run { + removeLongRunningTransaction(DisplayFirstTimelineItems)?.finish() + removeLongRunningTransaction(OpenRoom)?.finish() + removeLongRunningTransaction(NotificationTapOpensTimeline)?.finish() + } } .launchIn(this) combine(timelineController.timelineItems(), room.membersStateFlow) { items, membersState -> + val parent = analyticsService.getLongRunningTransaction(DisplayFirstTimelineItems) + val transaction = parent?.startChild("timelineItemsFactory.replaceWith", "Processing timeline items") + transaction?.setData("items", items.count()) timelineItemsFactory.replaceWith( timelineItems = items, roomMembers = membersState.roomMembers().orEmpty() ) + transaction?.finish() items } .onEach(redactedVoiceMessageManager::onEachMatrixTimelineItem) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt index 083777a7b7..5ff8e5d999 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt @@ -23,6 +23,7 @@ import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.libraries.matrix.api.roomlist.awaitLoaded import io.element.android.libraries.matrix.impl.room.preview.RoomPreviewInfoMapper import io.element.android.libraries.matrix.impl.roomlist.roomOrNull +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.recordTransaction import io.element.android.services.analyticsproviders.api.recordChildTransaction @@ -113,10 +114,13 @@ class RustRoomFactory( val sdkRoom = awaitRoomInRoomList(roomId) ?: return@withLock null + val parentTransaction = analyticsService.getLongRunningTransaction(AnalyticsLongRunningTransaction.OpenRoom) + if (sdkRoom.membership() == Membership.JOINED) { analyticsService.recordTransaction( name = "Get joined room", operation = "RustRoomFactory.getJoinedRoomOrPreview", + parentTransaction = parentTransaction, ) { transaction -> val hideThreadedEvents = featureFlagService.isFeatureEnabled(FeatureFlags.Threads) // Init the live timeline in the SDK from the Room @@ -136,9 +140,10 @@ class RustRoomFactory( ) } + val baseRoom = transaction.recordChildTransaction(operation = "getBaseRoom", description = "Get room from SDK") { getBaseRoom(sdkRoom) } GetRoomResult.Joined( JoinedRustRoom( - baseRoom = getBaseRoom(sdkRoom), + baseRoom = baseRoom, notificationSettingsService = notificationSettingsService, roomContentForwarder = roomContentForwarder, liveInnerTimeline = timeline, @@ -152,6 +157,7 @@ class RustRoomFactory( analyticsService.recordTransaction( name = "Get preview of room", operation = "RustRoomFactory.getJoinedRoomOrPreview", + parentTransaction = parentTransaction, ) { val preview = try { sdkRoom.previewRoom(via = serverNames) diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt index b173b2cb8f..b318807a45 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsLongRunningTransaction.kt @@ -16,4 +16,7 @@ sealed class AnalyticsLongRunningTransaction( data object ResumeAppUntilNewRoomsReceived : AnalyticsLongRunningTransaction("App was resumed and new room list items arrived", null) data object NotificationTapOpensTimeline : AnalyticsLongRunningTransaction("A notification was tapped and it opened a timeline", null) data object OpenRoom : AnalyticsLongRunningTransaction("Open a room and see loaded items in the timeline", null) + data object LoadJoinedRoomFlow : AnalyticsLongRunningTransaction("Load joined room UI", "ui.load") + data object LoadMessagesUi : AnalyticsLongRunningTransaction("Load messages UI", "ui.load") + data object DisplayFirstTimelineItems : AnalyticsLongRunningTransaction("Get and display first timeline items", null) } diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt index 726ec4180d..1e95263509 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt @@ -58,7 +58,10 @@ interface AnalyticsService : AnalyticsTracker, ErrorTracker { /** * Starts an [AnalyticsLongRunningTransaction], that can be shared with other components. */ - fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction + fun startLongRunningTransaction( + longRunningTransaction: AnalyticsLongRunningTransaction, + parentTransaction: AnalyticsTransaction? = null + ): AnalyticsTransaction /** * Gets an ongoing [AnalyticsLongRunningTransaction], if it exists. @@ -71,8 +74,14 @@ interface AnalyticsService : AnalyticsTracker, ErrorTracker { fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? } -inline fun AnalyticsService.recordTransaction(name: String, operation: String, block: (AnalyticsTransaction) -> T): T { - val transaction = startTransaction(name, operation) +inline fun AnalyticsService.recordTransaction( + name: String, + operation: String, + parentTransaction: AnalyticsTransaction? = null, + block: (AnalyticsTransaction) -> T +): T { + val transaction = parentTransaction?.startChild(name, operation) + ?: startTransaction(name, operation) try { val result = block(transaction) return result diff --git a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt index 83c76dc2fe..f1a5b444de 100644 --- a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/DefaultAnalyticsService.kt @@ -153,8 +153,13 @@ class DefaultAnalyticsService( } ?: NoopAnalyticsTransaction } - override fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction { - val transaction = startTransaction(longRunningTransaction.name, longRunningTransaction.operation) + override fun startLongRunningTransaction( + longRunningTransaction: AnalyticsLongRunningTransaction, + parentTransaction: AnalyticsTransaction?, + ): AnalyticsTransaction { + val transaction = parentTransaction?.startChild(longRunningTransaction.name, longRunningTransaction.operation) + ?: startTransaction(longRunningTransaction.name, longRunningTransaction.operation) + pendingLongRunningTransactions[longRunningTransaction] = transaction return transaction } diff --git a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt index 36eeaa0aa2..591651ed6c 100644 --- a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt +++ b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/NoopAnalyticsService.kt @@ -39,7 +39,10 @@ class NoopAnalyticsService : AnalyticsService { override fun trackError(throwable: Throwable) = Unit override fun updateSuperProperties(updatedProperties: SuperProperties) = Unit override fun startTransaction(name: String, operation: String?): AnalyticsTransaction = NoopAnalyticsTransaction - override fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction = NoopAnalyticsTransaction + override fun startLongRunningTransaction( + longRunningTransaction: AnalyticsLongRunningTransaction, + parentTransaction: AnalyticsTransaction?, + ): AnalyticsTransaction = NoopAnalyticsTransaction override fun getLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction? = null override fun removeLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction) = NoopAnalyticsTransaction } diff --git a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt index 9899ced193..274d06f6a5 100644 --- a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt +++ b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/FakeAnalyticsService.kt @@ -71,7 +71,10 @@ class FakeAnalyticsService( } override fun startTransaction(name: String, operation: String?): AnalyticsTransaction = NoopAnalyticsTransaction - override fun startLongRunningTransaction(longRunningTransaction: AnalyticsLongRunningTransaction): AnalyticsTransaction { + override fun startLongRunningTransaction( + longRunningTransaction: AnalyticsLongRunningTransaction, + parentTransaction: AnalyticsTransaction? + ): AnalyticsTransaction { longRunningTransactions[longRunningTransaction] = NoopAnalyticsTransaction return NoopAnalyticsTransaction } diff --git a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt index 5ed346aa6c..90bbd77e00 100644 --- a/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt +++ b/services/analyticsproviders/sentry/src/main/kotlin/io/element/android/services/analyticsproviders/sentry/SentryAnalyticsTransaction.kt @@ -9,7 +9,9 @@ package io.element.android.services.analyticsproviders.sentry import io.element.android.services.analyticsproviders.api.AnalyticsTransaction import io.sentry.ISpan +import io.sentry.ITransaction import io.sentry.Sentry +import timber.log.Timber class SentryAnalyticsTransaction private constructor(span: ISpan) : AnalyticsTransaction { constructor(name: String, operation: String?) : this(Sentry.startTransaction(name, operation.orEmpty())) @@ -20,5 +22,9 @@ class SentryAnalyticsTransaction private constructor(span: ISpan) : AnalyticsTra ) override fun setData(key: String, value: Any) = inner.setData(key, value) override fun isFinished(): Boolean = inner.isFinished - override fun finish() = inner.finish() + override fun finish() { + val name = if (inner is ITransaction) inner.name else inner.operation + Timber.d("Finishing transaction: $name") + inner.finish() + } } From 055b9f67a002404c246972f3940772eadef9280c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 20 Nov 2025 12:45:52 +0100 Subject: [PATCH 093/113] Add tests for `DefaultAnalyticsColdStartWatcher` --- .../analytics/AnalyticsColdStartWatcher.kt | 1 - .../DefaultAnalyticsColdStartWatcherTest.kt | 107 ++++++++++++++++++ 2 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 appnav/src/test/kotlin/io/element/android/appnav/analytics/DefaultAnalyticsColdStartWatcherTest.kt diff --git a/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt b/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt index 0782973cc4..8b9efa94bf 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt @@ -11,7 +11,6 @@ import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.SingleIn import io.element.android.libraries.di.annotations.AppCoroutineScope -import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList import io.element.android.services.analytics.api.AnalyticsService import kotlinx.coroutines.CoroutineScope diff --git a/appnav/src/test/kotlin/io/element/android/appnav/analytics/DefaultAnalyticsColdStartWatcherTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/analytics/DefaultAnalyticsColdStartWatcherTest.kt new file mode 100644 index 0000000000..d71d51faba --- /dev/null +++ b/appnav/src/test/kotlin/io/element/android/appnav/analytics/DefaultAnalyticsColdStartWatcherTest.kt @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.appnav.analytics + +import com.google.common.truth.Truth.assertThat +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList +import io.element.android.services.analytics.test.FakeAnalyticsService +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.test.TestScope +import kotlinx.coroutines.test.runCurrent +import kotlinx.coroutines.test.runTest +import org.junit.Test + +@OptIn(ExperimentalCoroutinesApi::class) +class DefaultAnalyticsColdStartWatcherTest { + @Test + fun `watch - until room list is visible`() = runTest { + val analyticsService = FakeAnalyticsService() + val watcher = createAnalyticsColdStartWatcher(analyticsService) + + // Start watching + watcher.start() + + // The user has given analytics consent, we can start tracking the cold start + analyticsService.setUserConsent(true) + runCurrent() + + // The transaction is running + assertThat(analyticsService.getLongRunningTransaction(ColdStartUntilCachedRoomList)).isNotNull() + + // As soon as the room list is visible + watcher.onRoomListVisible() + runCurrent() + + // The transaction is now finished + assertThat(analyticsService.getLongRunningTransaction(ColdStartUntilCachedRoomList)).isNull() + } + + @Test + fun `watch - user is logging in, transaction is cancelled since it's not a cold start`() = runTest { + val analyticsService = FakeAnalyticsService() + val watcher = createAnalyticsColdStartWatcher(analyticsService) + + // Start watching + watcher.start() + + // The user has given analytics consent, we can start tracking the cold start + analyticsService.setUserConsent(true) + runCurrent() + + // The transaction is running + assertThat(analyticsService.getLongRunningTransaction(ColdStartUntilCachedRoomList)).isNotNull() + + // If the user starts a login flow + watcher.whenLoggingIn() + runCurrent() + + // The transaction is gone + assertThat(analyticsService.getLongRunningTransaction(ColdStartUntilCachedRoomList)).isNull() + } + + @Test + fun `watch - user was logging in, transaction is never started since it's not a cold start`() = runTest { + val analyticsService = FakeAnalyticsService() + val watcher = createAnalyticsColdStartWatcher(analyticsService) + + // Start watching + watcher.start() + + // If the user starts a login flow + watcher.whenLoggingIn() + + // The user has given analytics consent, we can start tracking the cold start + analyticsService.setUserConsent(true) + runCurrent() + + // The transaction never starts + assertThat(analyticsService.getLongRunningTransaction(ColdStartUntilCachedRoomList)).isNull() + } + + @Test + fun `watch - never gets consent so it does nothing`() = runTest { + val analyticsService = FakeAnalyticsService() + val watcher = createAnalyticsColdStartWatcher(analyticsService) + + // Start watching + watcher.start() + + // The user never gets the analytics consent, so we do nothing + runCurrent() + + // The transaction is not running in that case + assertThat(analyticsService.getLongRunningTransaction(ColdStartUntilCachedRoomList)).isNull() + } + + private fun TestScope.createAnalyticsColdStartWatcher( + analyticsService: FakeAnalyticsService = FakeAnalyticsService(), + ) = DefaultAnalyticsColdStartWatcher( + analyticsService = analyticsService, + appCoroutineScope = backgroundScope, + ) +} From 04feea5d255a8c9ad6029af536d51aebe6157e54 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 27 Nov 2025 12:13:16 +0100 Subject: [PATCH 094/113] Move analytic watchers to `:services:analytics` --- .../android/appnav/LoggedInFlowNode.kt | 2 +- .../android/appnav/NotLoggedInFlowNode.kt | 2 +- .../io/element/android/appnav/RootFlowNode.kt | 1 + features/home/impl/build.gradle.kts | 1 - .../home/impl/roomlist/RoomListPresenter.kt | 2 +- .../impl/roomlist/RoomListPresenterTest.kt | 10 +------ .../api/watchers/AnalyticsColdStartWatcher.kt | 18 ++++++++++++ .../watchers/AnalyticsRoomListStateWatcher.kt | 17 +++++++++++ services/analytics/impl/build.gradle.kts | 4 +++ .../DefaultAnalyticsColdStartWatcher.kt | 21 ++++---------- .../DefaultAnalyticsRoomListStateWatcher.kt | 29 +++++++++---------- .../DefaultAnalyticsColdStartWatcherTest.kt | 2 +- ...efaultAnalyticsRoomListStateWatcherTest.kt | 6 ++-- .../watchers/FakeAnalyticsColdStartWatcher.kt | 16 ++++++++++ 14 files changed, 84 insertions(+), 47 deletions(-) create mode 100644 services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/watchers/AnalyticsColdStartWatcher.kt create mode 100644 services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/watchers/AnalyticsRoomListStateWatcher.kt rename appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt => services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcher.kt (73%) rename appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcher.kt => services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt (77%) rename {appnav/src/test/kotlin/io/element/android/appnav/analytics => services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers}/DefaultAnalyticsColdStartWatcherTest.kt (98%) rename appnav/src/test/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcherTest.kt => services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcherTest.kt (97%) create mode 100644 services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/watchers/FakeAnalyticsColdStartWatcher.kt diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index 310913e0ac..7e782c7cc4 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -41,7 +41,6 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import im.vector.app.features.analytics.plan.JoinedRoom import io.element.android.annotations.ContributesNode -import io.element.android.appnav.analytics.AnalyticsRoomListStateWatcher import io.element.android.appnav.loggedin.LoggedInNode import io.element.android.appnav.loggedin.MediaPreviewConfigMigration import io.element.android.appnav.loggedin.SendQueues @@ -93,6 +92,7 @@ import io.element.android.libraries.push.api.notifications.conversations.Notific import io.element.android.libraries.ui.common.nodes.emptyNode import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.watchers.AnalyticsRoomListStateWatcher import io.element.android.services.appnavstate.api.AppNavigationStateService import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.first diff --git a/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt index b1d371b4c0..080f3c1d77 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/NotLoggedInFlowNode.kt @@ -24,7 +24,6 @@ import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import io.element.android.annotations.ContributesNode -import io.element.android.appnav.analytics.AnalyticsColdStartWatcher import io.element.android.features.login.api.LoginEntryPoint import io.element.android.features.login.api.LoginParams import io.element.android.libraries.architecture.BackstackView @@ -35,6 +34,7 @@ import io.element.android.libraries.architecture.inputs import io.element.android.libraries.designsystem.utils.ForceOrientationInMobileDevices import io.element.android.libraries.designsystem.utils.ScreenOrientation import io.element.android.libraries.matrix.ui.media.ImageLoaderHolder +import io.element.android.services.analytics.api.watchers.AnalyticsColdStartWatcher import kotlinx.parcelize.Parcelize @ContributesNode(AppScope::class) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt index 52788fc992..838804a055 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt @@ -65,6 +65,7 @@ import io.element.android.libraries.sessionstorage.api.SessionStore import io.element.android.libraries.ui.common.nodes.emptyNode import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.watchers.AnalyticsColdStartWatcher import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach diff --git a/features/home/impl/build.gradle.kts b/features/home/impl/build.gradle.kts index 9362702a1a..b36ee6aed2 100644 --- a/features/home/impl/build.gradle.kts +++ b/features/home/impl/build.gradle.kts @@ -28,7 +28,6 @@ setupDependencyInjection() dependencies { implementation(projects.appconfig) - implementation(projects.appnav) implementation(projects.libraries.core) implementation(projects.libraries.androidutils) implementation(projects.libraries.architecture) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt index ce1197f9ca..5fc07ab21c 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenter.kt @@ -25,7 +25,6 @@ import androidx.compose.runtime.setValue import androidx.compose.runtime.snapshotFlow import dev.zacsweers.metro.Inject import im.vector.app.features.analytics.plan.Interaction -import io.element.android.appnav.analytics.AnalyticsColdStartWatcher import io.element.android.features.announcement.api.Announcement import io.element.android.features.announcement.api.AnnouncementService import io.element.android.features.home.impl.datasource.RoomListDataSource @@ -52,6 +51,7 @@ import io.element.android.libraries.preferences.api.store.SessionPreferencesStor import io.element.android.libraries.push.api.battery.BatteryOptimizationState import io.element.android.libraries.push.api.notifications.NotificationCleaner import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.watchers.AnalyticsColdStartWatcher import io.element.android.services.analyticsproviders.api.trackers.captureInteraction import kotlinx.collections.immutable.toImmutableList import kotlinx.collections.immutable.toImmutableSet diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt index a3be896f40..acc68db018 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/roomlist/RoomListPresenterTest.kt @@ -13,7 +13,6 @@ import app.cash.molecule.moleculeFlow import app.cash.turbine.test import com.google.common.truth.Truth.assertThat import im.vector.app.features.analytics.plan.Interaction -import io.element.android.appnav.analytics.AnalyticsColdStartWatcher import io.element.android.features.announcement.api.Announcement import io.element.android.features.announcement.api.AnnouncementService import io.element.android.features.home.impl.FakeDateTimeObserver @@ -71,6 +70,7 @@ import io.element.android.libraries.push.api.notifications.NotificationCleaner import io.element.android.libraries.push.test.notifications.FakeNotificationCleaner import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.test.FakeAnalyticsService +import io.element.android.services.analytics.test.watchers.FakeAnalyticsColdStartWatcher import io.element.android.tests.testutils.EventsRecorder import io.element.android.tests.testutils.WarmUpRule import io.element.android.tests.testutils.consumeItemsUntilPredicate @@ -677,11 +677,3 @@ class RoomListPresenterTest { coldStartWatcher = FakeAnalyticsColdStartWatcher(), ) } - -private class FakeAnalyticsColdStartWatcher : AnalyticsColdStartWatcher { - override fun start() {} - - override fun whenLoggingIn() {} - - override fun onRoomListVisible() {} -} diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/watchers/AnalyticsColdStartWatcher.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/watchers/AnalyticsColdStartWatcher.kt new file mode 100644 index 0000000000..67d3c5498b --- /dev/null +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/watchers/AnalyticsColdStartWatcher.kt @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.services.analytics.api.watchers + +/** + * Adds a performance check transaction measuring the time between a cold start (or, after we read the user consent after a cold start) + * until the cached room list is displayed. This check only takes place in a cold app start after the user is authenticated. + */ +interface AnalyticsColdStartWatcher { + fun start() + fun whenLoggingIn() + fun onRoomListVisible() +} diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/watchers/AnalyticsRoomListStateWatcher.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/watchers/AnalyticsRoomListStateWatcher.kt new file mode 100644 index 0000000000..2f6d4723a3 --- /dev/null +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/watchers/AnalyticsRoomListStateWatcher.kt @@ -0,0 +1,17 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.services.analytics.api.watchers + +/** + * This component is used to check how long it takes for the room list to be up to date after opening the app while it's on a 'warm' state: + * the app was previously running and we just returned to it. + */ +interface AnalyticsRoomListStateWatcher { + fun start() + fun stop() +} diff --git a/services/analytics/impl/build.gradle.kts b/services/analytics/impl/build.gradle.kts index 8aa542f60a..6ba2963853 100644 --- a/services/analytics/impl/build.gradle.kts +++ b/services/analytics/impl/build.gradle.kts @@ -25,16 +25,20 @@ dependencies { implementation(projects.libraries.core) implementation(projects.libraries.architecture) implementation(projects.libraries.designsystem) + implementation(projects.libraries.matrix.api) implementation(projects.libraries.preferences.api) implementation(projects.libraries.sessionStorage.api) + implementation(projects.services.appnavstate.api) api(projects.services.analyticsproviders.api) api(projects.services.analytics.api) implementation(libs.androidx.datastore.preferences) testCommonDependencies(libs) + testImplementation(projects.libraries.matrix.test) testImplementation(projects.libraries.sessionStorage.test) testImplementation(projects.services.analytics.test) testImplementation(projects.services.analyticsproviders.test) + testImplementation(projects.services.appnavstate.test) testImplementation(projects.services.toolbox.test) } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcher.kt similarity index 73% rename from appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt rename to services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcher.kt index 8b9efa94bf..f5ef72ba8d 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsColdStartWatcher.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcher.kt @@ -5,14 +5,15 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.appnav.analytics +package io.element.android.services.analytics.impl.watchers import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding import dev.zacsweers.metro.SingleIn import io.element.android.libraries.di.annotations.AppCoroutineScope -import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.watchers.AnalyticsColdStartWatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.catch import kotlinx.coroutines.flow.launchIn @@ -20,16 +21,6 @@ import kotlinx.coroutines.flow.onEach import timber.log.Timber import java.util.concurrent.atomic.AtomicBoolean -/** - * Adds a performance check transaction measuring the time between a cold start (or, after we read the user consent after a cold start) - * until the cached room list is displayed. This check only takes place in a cold app start after the user is authenticated. - */ -interface AnalyticsColdStartWatcher { - fun start() - fun whenLoggingIn() - fun onRoomListVisible() -} - @SingleIn(AppScope::class) @ContributesBinding(AppScope::class) class DefaultAnalyticsColdStartWatcher( @@ -44,7 +35,7 @@ class DefaultAnalyticsColdStartWatcher( if (hasConsent) { if (isColdStart.get()) { Timber.d("Starting cold start check") - analyticsService.startLongRunningTransaction(ColdStartUntilCachedRoomList) + analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList) } else { error("The app is no longer in a cold start state") } @@ -56,7 +47,7 @@ class DefaultAnalyticsColdStartWatcher( override fun whenLoggingIn() { if (isColdStart.getAndSet(false)) { - analyticsService.removeLongRunningTransaction(ColdStartUntilCachedRoomList) + analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList) Timber.d("Canceled cold start check: user is logging in") } } @@ -64,7 +55,7 @@ class DefaultAnalyticsColdStartWatcher( override fun onRoomListVisible() { if (isColdStart.getAndSet(false)) { Timber.d("Room list is visible, finishing cold start check") - analyticsService.removeLongRunningTransaction(ColdStartUntilCachedRoomList)?.finish() + analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList)?.finish() } } } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcher.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt similarity index 77% rename from appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcher.kt rename to services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt index 91efa0bf92..c2a82eb49b 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcher.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt @@ -5,15 +5,18 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.appnav.analytics +package io.element.android.services.analytics.impl.watchers -import dev.zacsweers.metro.Inject +import dev.zacsweers.metro.ContributesBinding import io.element.android.libraries.core.coroutine.CoroutineDispatchers +import io.element.android.libraries.core.coroutine.childScope import io.element.android.libraries.core.coroutine.withPreviousValue +import io.element.android.libraries.di.SessionScope import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.matrix.api.roomlist.RoomListService -import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.ResumeAppUntilNewRoomsReceived +import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.watchers.AnalyticsRoomListStateWatcher import io.element.android.services.appnavstate.api.AppNavigationStateService import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.cancel @@ -24,35 +27,31 @@ import kotlinx.coroutines.flow.onEach import timber.log.Timber import java.util.concurrent.atomic.AtomicBoolean -/** - * This component is used to check how long it takes for the room list to be up to date after opening the app while it's on a 'warm' state: - * the app was previously running and we just returned to it. - */ -@Inject -class AnalyticsRoomListStateWatcher( +@ContributesBinding(SessionScope::class) +class DefaultAnalyticsRoomListStateWatcher( private val appNavigationStateService: AppNavigationStateService, private val roomListService: RoomListService, private val analyticsService: AnalyticsService, @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, private val dispatchers: CoroutineDispatchers, -) { +) : AnalyticsRoomListStateWatcher { private var currentCoroutineScope: CoroutineScope? = null private val isWarmState = AtomicBoolean(false) - fun start() { + override fun start() { if (currentCoroutineScope != null) { Timber.w("Can't start RoomListStateWatcher, it's already running.") return } - val coroutineScope = CoroutineScope(sessionCoroutineScope.coroutineContext + dispatchers.computation) + val coroutineScope = sessionCoroutineScope.childScope(dispatchers.computation, "AnalyticsRoomListStateWatcher") appNavigationStateService.appNavigationState .map { it.isInForeground } .distinctUntilChanged() .withPreviousValue() .onEach { (wasInForeground, isInForeground) -> if (isInForeground && roomListService.state.value != RoomListService.State.Running) { - analyticsService.startLongRunningTransaction(ResumeAppUntilNewRoomsReceived) + analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.ResumeAppUntilNewRoomsReceived) } if (wasInForeground == false && isInForeground) { @@ -64,7 +63,7 @@ class AnalyticsRoomListStateWatcher( roomListService.state .onEach { state -> if (state == RoomListService.State.Running && isWarmState.get()) { - analyticsService.removeLongRunningTransaction(ResumeAppUntilNewRoomsReceived)?.finish() + analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.ResumeAppUntilNewRoomsReceived)?.finish() } } .launchIn(coroutineScope) @@ -72,7 +71,7 @@ class AnalyticsRoomListStateWatcher( currentCoroutineScope = coroutineScope } - fun stop() { + override fun stop() { currentCoroutineScope?.cancel() currentCoroutineScope = null } diff --git a/appnav/src/test/kotlin/io/element/android/appnav/analytics/DefaultAnalyticsColdStartWatcherTest.kt b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcherTest.kt similarity index 98% rename from appnav/src/test/kotlin/io/element/android/appnav/analytics/DefaultAnalyticsColdStartWatcherTest.kt rename to services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcherTest.kt index d71d51faba..325316b45c 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/analytics/DefaultAnalyticsColdStartWatcherTest.kt +++ b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcherTest.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.appnav.analytics +package io.element.android.services.analytics.impl.watchers import com.google.common.truth.Truth.assertThat import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList diff --git a/appnav/src/test/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcherTest.kt b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcherTest.kt similarity index 97% rename from appnav/src/test/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcherTest.kt rename to services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcherTest.kt index f05190acc7..3b1f562c67 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/analytics/AnalyticsRoomListStateWatcherTest.kt +++ b/services/analytics/impl/src/test/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcherTest.kt @@ -5,7 +5,7 @@ * Please see LICENSE files in the repository root for full details. */ -package io.element.android.appnav.analytics +package io.element.android.services.analytics.impl.watchers import com.google.common.truth.Truth.assertThat import io.element.android.libraries.matrix.api.roomlist.RoomListService @@ -23,7 +23,7 @@ import kotlinx.coroutines.test.runTest import org.junit.Test @OptIn(ExperimentalCoroutinesApi::class) -class AnalyticsRoomListStateWatcherTest { +class DefaultAnalyticsRoomListStateWatcherTest { @Test fun `Opening the app in a warm state tracks the time until the room list is synced`() = runTest { val navigationStateService = FakeAppNavigationStateService() @@ -160,7 +160,7 @@ class AnalyticsRoomListStateWatcherTest { appNavigationStateService: FakeAppNavigationStateService = FakeAppNavigationStateService(), roomListService: FakeRoomListService = FakeRoomListService(), analyticsService: FakeAnalyticsService = FakeAnalyticsService(), - ) = AnalyticsRoomListStateWatcher( + ) = DefaultAnalyticsRoomListStateWatcher( appNavigationStateService = appNavigationStateService, roomListService = roomListService, analyticsService = analyticsService, diff --git a/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/watchers/FakeAnalyticsColdStartWatcher.kt b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/watchers/FakeAnalyticsColdStartWatcher.kt new file mode 100644 index 0000000000..ad13c8422d --- /dev/null +++ b/services/analytics/test/src/main/kotlin/io/element/android/services/analytics/test/watchers/FakeAnalyticsColdStartWatcher.kt @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.services.analytics.test.watchers + +import io.element.android.services.analytics.api.watchers.AnalyticsColdStartWatcher + +class FakeAnalyticsColdStartWatcher : AnalyticsColdStartWatcher { + override fun start() {} + override fun whenLoggingIn() {} + override fun onRoomListVisible() {} +} From 1d77aa447d92fe349c82590a5b169130ee9fc214 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 27 Nov 2025 12:17:51 +0100 Subject: [PATCH 095/113] Extract `from_notification` extra to a constant in `IntentNavigationExtras` Allow `IntentProvider` to receive extras and `PendingIntentFactory` to send them. --- .../android/x/intent/DefaultIntentProvider.kt | 4 +++- .../io/element/android/appnav/RootFlowNode.kt | 5 +++-- .../push/impl/intent/IntentProvider.kt | 2 ++ .../factories/NotificationCreator.kt | 22 ++++++++++++++++--- .../factories/PendingIntentFactory.kt | 17 +++++++------- .../factories/FakeIntentProvider.kt | 9 +++++++- .../appnavstate/api/IntentNavigationExtras.kt | 10 +++++++++ 7 files changed, 54 insertions(+), 15 deletions(-) create mode 100644 services/appnavstate/api/src/main/kotlin/io/element/android/services/appnavstate/api/IntentNavigationExtras.kt diff --git a/app/src/main/kotlin/io/element/android/x/intent/DefaultIntentProvider.kt b/app/src/main/kotlin/io/element/android/x/intent/DefaultIntentProvider.kt index a4272063ba..0453fdf160 100644 --- a/app/src/main/kotlin/io/element/android/x/intent/DefaultIntentProvider.kt +++ b/app/src/main/kotlin/io/element/android/x/intent/DefaultIntentProvider.kt @@ -10,6 +10,7 @@ package io.element.android.x.intent import android.content.Context import android.content.Intent +import android.os.Bundle import androidx.core.net.toUri import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding @@ -32,11 +33,12 @@ class DefaultIntentProvider( roomId: RoomId?, threadId: ThreadId?, eventId: EventId?, + extras: Bundle?, ): Intent { return Intent(context, MainActivity::class.java).apply { action = Intent.ACTION_VIEW data = deepLinkCreator.create(sessionId, roomId, threadId, eventId).toUri() - putExtra("from_notification", true) + extras?.let(::putExtras) } } } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt index 838804a055..4687946367 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/RootFlowNode.kt @@ -29,7 +29,6 @@ import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject import im.vector.app.features.analytics.plan.JoinedRoom import io.element.android.annotations.ContributesNode -import io.element.android.appnav.analytics.AnalyticsColdStartWatcher import io.element.android.appnav.di.MatrixSessionCache import io.element.android.appnav.intent.IntentResolver import io.element.android.appnav.intent.ResolvedIntent @@ -66,6 +65,7 @@ import io.element.android.libraries.ui.common.nodes.emptyNode import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction import io.element.android.services.analytics.api.AnalyticsService import io.element.android.services.analytics.api.watchers.AnalyticsColdStartWatcher +import io.element.android.services.appnavstate.api.ROOM_OPENED_FROM_NOTIFICATION import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach @@ -318,7 +318,8 @@ class RootFlowNode( val resolvedIntent = intentResolver.resolve(intent) ?: return when (resolvedIntent) { is ResolvedIntent.Navigation -> { - if (intent.getBooleanExtra("from_notification", false) && resolvedIntent.deeplinkData is DeeplinkData.Room) { + val openingRoomFromNotification = intent.getBooleanExtra(ROOM_OPENED_FROM_NOTIFICATION, false) + if (openingRoomFromNotification && resolvedIntent.deeplinkData is DeeplinkData.Room) { analyticsService.startLongRunningTransaction(AnalyticsLongRunningTransaction.NotificationTapOpensTimeline) } navigateTo(resolvedIntent.deeplinkData) diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/intent/IntentProvider.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/intent/IntentProvider.kt index b4b0d92888..82ee730d17 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/intent/IntentProvider.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/intent/IntentProvider.kt @@ -9,6 +9,7 @@ package io.element.android.libraries.push.impl.intent import android.content.Intent +import android.os.Bundle import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId @@ -23,5 +24,6 @@ interface IntentProvider { roomId: RoomId?, threadId: ThreadId?, eventId: EventId?, + extras: Bundle? = null, ): Intent } diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/NotificationCreator.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/NotificationCreator.kt index ff969c2b84..9533f6b0ac 100755 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/NotificationCreator.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/NotificationCreator.kt @@ -15,6 +15,7 @@ import androidx.annotation.ColorInt import androidx.core.app.NotificationCompat import androidx.core.app.NotificationCompat.MessagingStyle import androidx.core.app.Person +import androidx.core.os.bundleOf import coil3.ImageLoader import dev.zacsweers.metro.AppScope import dev.zacsweers.metro.ContributesBinding @@ -44,6 +45,7 @@ import io.element.android.libraries.push.impl.notifications.model.NotifiableMess import io.element.android.libraries.push.impl.notifications.model.SimpleNotifiableEvent import io.element.android.libraries.push.impl.notifications.shortcut.createShortcutId import io.element.android.libraries.ui.strings.CommonStrings +import io.element.android.services.appnavstate.api.ROOM_OPENED_FROM_NOTIFICATION import io.element.android.services.toolbox.api.strings.StringProvider interface NotificationCreator { @@ -138,7 +140,12 @@ class DefaultNotificationCreator( val eventId = events.firstOrNull()?.eventId val openIntent = when { threadId != null -> pendingIntentFactory.createOpenThreadPendingIntent(roomInfo.sessionId, roomInfo.roomId, eventId, threadId) - else -> pendingIntentFactory.createOpenRoomPendingIntent(roomInfo.sessionId, roomInfo.roomId, eventId) + else -> pendingIntentFactory.createOpenRoomPendingIntent( + sessionId = roomInfo.sessionId, + roomId = roomInfo.roomId, + eventId = eventId, + extras = bundleOf(ROOM_OPENED_FROM_NOTIFICATION to true), + ) } val containsMissedCall = events.any { it.type == EventType.RTC_NOTIFICATION } val channelId = if (containsMissedCall) { @@ -233,7 +240,11 @@ class DefaultNotificationCreator( .addAction(rejectInvitationActionFactory.create(inviteNotifiableEvent)) .addAction(acceptInvitationActionFactory.create(inviteNotifiableEvent)) // Build the pending intent for when the notification is clicked - .setContentIntent(pendingIntentFactory.createOpenRoomPendingIntent(inviteNotifiableEvent.sessionId, inviteNotifiableEvent.roomId, null)) + .setContentIntent(pendingIntentFactory.createOpenRoomPendingIntent( + sessionId = inviteNotifiableEvent.sessionId, + roomId = inviteNotifiableEvent.roomId, + eventId = null, + )) .apply { if (inviteNotifiableEvent.noisy) { // Compat @@ -265,7 +276,12 @@ class DefaultNotificationCreator( .setGroupAlertBehavior(NotificationCompat.GROUP_ALERT_ALL) .configureWith(notificationAccountParams) .setAutoCancel(true) - .setContentIntent(pendingIntentFactory.createOpenRoomPendingIntent(simpleNotifiableEvent.sessionId, simpleNotifiableEvent.roomId, null)) + .setContentIntent(pendingIntentFactory.createOpenRoomPendingIntent( + sessionId = simpleNotifiableEvent.sessionId, + roomId = simpleNotifiableEvent.roomId, + eventId = null, + extras = bundleOf(ROOM_OPENED_FROM_NOTIFICATION to true), + )) .apply { if (simpleNotifiableEvent.noisy) { // Compat diff --git a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/PendingIntentFactory.kt b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/PendingIntentFactory.kt index e68efebb14..07fa70a6c8 100644 --- a/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/PendingIntentFactory.kt +++ b/libraries/push/impl/src/main/kotlin/io/element/android/libraries/push/impl/notifications/factories/PendingIntentFactory.kt @@ -11,6 +11,7 @@ package io.element.android.libraries.push.impl.notifications.factories import android.app.PendingIntent import android.content.Context import android.content.Intent +import android.os.Bundle import dev.zacsweers.metro.Inject import io.element.android.libraries.androidutils.uri.createIgnoredUri import io.element.android.libraries.di.annotations.ApplicationContext @@ -31,20 +32,20 @@ class PendingIntentFactory( private val clock: SystemClock, private val actionIds: NotificationActionIds, ) { - fun createOpenSessionPendingIntent(sessionId: SessionId): PendingIntent? { - return createRoomPendingIntent(sessionId = sessionId, roomId = null, eventId = null, threadId = null) + fun createOpenSessionPendingIntent(sessionId: SessionId, extras: Bundle? = null): PendingIntent? { + return createRoomPendingIntent(sessionId = sessionId, roomId = null, eventId = null, threadId = null, extras = extras) } - fun createOpenRoomPendingIntent(sessionId: SessionId, roomId: RoomId, eventId: EventId?): PendingIntent? { - return createRoomPendingIntent(sessionId = sessionId, roomId = roomId, eventId = eventId, threadId = null) + fun createOpenRoomPendingIntent(sessionId: SessionId, roomId: RoomId, eventId: EventId?, extras: Bundle? = null): PendingIntent? { + return createRoomPendingIntent(sessionId = sessionId, roomId = roomId, eventId = eventId, threadId = null, extras = extras) } - fun createOpenThreadPendingIntent(sessionId: SessionId, roomId: RoomId, eventId: EventId?, threadId: ThreadId): PendingIntent? { - return createRoomPendingIntent(sessionId = sessionId, roomId = roomId, eventId = eventId, threadId = threadId) + fun createOpenThreadPendingIntent(sessionId: SessionId, roomId: RoomId, eventId: EventId?, threadId: ThreadId, extras: Bundle? = null): PendingIntent? { + return createRoomPendingIntent(sessionId = sessionId, roomId = roomId, eventId = eventId, threadId = threadId, extras = extras) } - private fun createRoomPendingIntent(sessionId: SessionId, roomId: RoomId?, eventId: EventId?, threadId: ThreadId?): PendingIntent? { - val intent = intentProvider.getViewRoomIntent(sessionId = sessionId, roomId = roomId, eventId = eventId, threadId = threadId) + private fun createRoomPendingIntent(sessionId: SessionId, roomId: RoomId?, eventId: EventId?, threadId: ThreadId?, extras: Bundle? = null): PendingIntent? { + val intent = intentProvider.getViewRoomIntent(sessionId = sessionId, roomId = roomId, eventId = eventId, threadId = threadId, extras = extras) return PendingIntent.getActivity( context, clock.epochMillis().toInt(), diff --git a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/factories/FakeIntentProvider.kt b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/factories/FakeIntentProvider.kt index fdbe927190..62ab850ae7 100644 --- a/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/factories/FakeIntentProvider.kt +++ b/libraries/push/impl/src/test/kotlin/io/element/android/libraries/push/impl/notifications/factories/FakeIntentProvider.kt @@ -9,6 +9,7 @@ package io.element.android.libraries.push.impl.notifications.factories import android.content.Intent +import android.os.Bundle import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.SessionId @@ -16,5 +17,11 @@ import io.element.android.libraries.matrix.api.core.ThreadId import io.element.android.libraries.push.impl.intent.IntentProvider class FakeIntentProvider : IntentProvider { - override fun getViewRoomIntent(sessionId: SessionId, roomId: RoomId?, threadId: ThreadId?, eventId: EventId?) = Intent(Intent.ACTION_VIEW) + override fun getViewRoomIntent( + sessionId: SessionId, + roomId: RoomId?, + threadId: ThreadId?, + eventId: EventId?, + extras: Bundle?, + ) = Intent(Intent.ACTION_VIEW) } diff --git a/services/appnavstate/api/src/main/kotlin/io/element/android/services/appnavstate/api/IntentNavigationExtras.kt b/services/appnavstate/api/src/main/kotlin/io/element/android/services/appnavstate/api/IntentNavigationExtras.kt new file mode 100644 index 0000000000..4851503984 --- /dev/null +++ b/services/appnavstate/api/src/main/kotlin/io/element/android/services/appnavstate/api/IntentNavigationExtras.kt @@ -0,0 +1,10 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.services.appnavstate.api + +const val ROOM_OPENED_FROM_NOTIFICATION = "opened_from_notification" From 1c576fd42dabd1cc329a10d5bb95e2feacce2cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 27 Nov 2025 12:27:49 +0100 Subject: [PATCH 096/113] Add `AnalyticsService.cancelLongRunningTransaction` and `AnalyticsService.finishLongRunningTransaction` --- .../room/joined/JoinedRoomLoadedFlowNode.kt | 3 ++- .../features/messages/impl/MessagesNode.kt | 3 ++- .../impl/timeline/TimelinePresenter.kt | 7 ++++--- .../matrix/impl/roomlist/RoomListFactory.kt | 3 ++- .../analytics/api/AnalyticsService.kt | 21 +++++++++++++++++++ .../DefaultAnalyticsColdStartWatcher.kt | 6 ++++-- .../DefaultAnalyticsRoomListStateWatcher.kt | 3 ++- 7 files changed, 37 insertions(+), 9 deletions(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt index 3ff8e16b49..5a6ef9133b 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomLoadedFlowNode.kt @@ -49,6 +49,7 @@ import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.LoadMessagesUi import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.OpenRoom import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.finishLongRunningTransaction import io.element.android.services.appnavstate.api.ActiveRoomsHolder import io.element.android.services.appnavstate.api.AppNavigationStateService import kotlinx.coroutines.CoroutineScope @@ -107,7 +108,7 @@ class JoinedRoomLoadedFlowNode( trackVisitedRoom() }, onResume = { - analyticsService.removeLongRunningTransaction(LoadJoinedRoomFlow)?.finish() + analyticsService.finishLongRunningTransaction(LoadJoinedRoomFlow) sessionCoroutineScope.launch { inputs.room.subscribeToSync() } diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt index 2032d70d64..0692a98745 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/MessagesNode.kt @@ -70,6 +70,7 @@ import io.element.android.libraries.mediaplayer.api.MediaPlayer import io.element.android.libraries.ui.strings.CommonStrings import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.LoadMessagesUi import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.finishLongRunningTransaction import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.toImmutableList import kotlinx.coroutines.CoroutineScope @@ -138,7 +139,7 @@ class MessagesNode( sessionCoroutineScope.launch { analyticsService.capture(room.toAnalyticsViewRoom()) } }, onResume = { - analyticsService.removeLongRunningTransaction(LoadMessagesUi)?.finish() + analyticsService.finishLongRunningTransaction(LoadMessagesUi) }, onDestroy = { mediaPlayer.close() diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt index 3044822256..127dab0345 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt @@ -59,6 +59,7 @@ import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.NotificationTapOpensTimeline import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction.OpenRoom import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.finishLongRunningTransaction import kotlinx.collections.immutable.ImmutableList import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.CoroutineScope @@ -239,9 +240,9 @@ class TimelinePresenter( timelineItems = newTimelineItems analyticsService.run { - removeLongRunningTransaction(DisplayFirstTimelineItems)?.finish() - removeLongRunningTransaction(OpenRoom)?.finish() - removeLongRunningTransaction(NotificationTapOpensTimeline)?.finish() + finishLongRunningTransaction(DisplayFirstTimelineItems) + finishLongRunningTransaction(OpenRoom) + finishLongRunningTransaction(NotificationTapOpensTimeline) } } .launchIn(this) diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt index 1fd0871019..b15411c382 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/roomlist/RoomListFactory.kt @@ -14,6 +14,7 @@ import io.element.android.libraries.matrix.api.roomlist.RoomListFilter import io.element.android.libraries.matrix.api.roomlist.RoomSummary import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.finishLongRunningTransaction import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.MutableSharedFlow import kotlinx.coroutines.flow.MutableStateFlow @@ -73,7 +74,7 @@ internal class RoomListFactory( initialFilterKind = RoomListEntriesDynamicFilterKind.All(ROOM_LIST_RUST_FILTERS), ).onEach { update -> if (!firstRoomsTransaction.isFinished()) { - analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.FirstRoomsDisplayed)?.finish() + analyticsService.finishLongRunningTransaction(AnalyticsLongRunningTransaction.FirstRoomsDisplayed) firstRoomsTransaction.finish() } processor.postUpdate(update) diff --git a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt index 1e95263509..08562b01ce 100644 --- a/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt +++ b/services/analytics/api/src/main/kotlin/io/element/android/services/analytics/api/AnalyticsService.kt @@ -89,3 +89,24 @@ inline fun AnalyticsService.recordTransaction( transaction.finish() } } + +/** + * Cancels a long running transaction. It behaves the same as [AnalyticsService.removeLongRunningTransaction], + * but it doesn't return the transaction so we can't finish it later. + */ +fun AnalyticsService.cancelLongRunningTransaction( + longRunningTransaction: AnalyticsLongRunningTransaction +) = removeLongRunningTransaction(longRunningTransaction) + +/** + * Finishes a long running transaction if it exists. Optionally performs an [action] with the transaction before finishing it. + */ +fun AnalyticsService.finishLongRunningTransaction( + longRunningTransaction: AnalyticsLongRunningTransaction, + action: (AnalyticsTransaction) -> Unit = {}, +) { + removeLongRunningTransaction(longRunningTransaction)?.let { + action(it) + it.finish() + } +} diff --git a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcher.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcher.kt index f5ef72ba8d..c53e28918b 100644 --- a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcher.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsColdStartWatcher.kt @@ -13,6 +13,8 @@ import dev.zacsweers.metro.SingleIn import io.element.android.libraries.di.annotations.AppCoroutineScope import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.cancelLongRunningTransaction +import io.element.android.services.analytics.api.finishLongRunningTransaction import io.element.android.services.analytics.api.watchers.AnalyticsColdStartWatcher import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.catch @@ -47,7 +49,7 @@ class DefaultAnalyticsColdStartWatcher( override fun whenLoggingIn() { if (isColdStart.getAndSet(false)) { - analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList) + analyticsService.cancelLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList) Timber.d("Canceled cold start check: user is logging in") } } @@ -55,7 +57,7 @@ class DefaultAnalyticsColdStartWatcher( override fun onRoomListVisible() { if (isColdStart.getAndSet(false)) { Timber.d("Room list is visible, finishing cold start check") - analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList)?.finish() + analyticsService.finishLongRunningTransaction(AnalyticsLongRunningTransaction.ColdStartUntilCachedRoomList) } } } diff --git a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt index c2a82eb49b..cd1af657b2 100644 --- a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt @@ -16,6 +16,7 @@ import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.matrix.api.roomlist.RoomListService import io.element.android.services.analytics.api.AnalyticsLongRunningTransaction import io.element.android.services.analytics.api.AnalyticsService +import io.element.android.services.analytics.api.finishLongRunningTransaction import io.element.android.services.analytics.api.watchers.AnalyticsRoomListStateWatcher import io.element.android.services.appnavstate.api.AppNavigationStateService import kotlinx.coroutines.CoroutineScope @@ -63,7 +64,7 @@ class DefaultAnalyticsRoomListStateWatcher( roomListService.state .onEach { state -> if (state == RoomListService.State.Running && isWarmState.get()) { - analyticsService.removeLongRunningTransaction(AnalyticsLongRunningTransaction.ResumeAppUntilNewRoomsReceived)?.finish() + analyticsService.finishLongRunningTransaction(AnalyticsLongRunningTransaction.ResumeAppUntilNewRoomsReceived) } } .launchIn(coroutineScope) From ed020114dc9edca15941a3f1cb6e0bd5b682b001 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Thu, 27 Nov 2025 13:29:20 +0100 Subject: [PATCH 097/113] Add `Noop` variants for the new watcher interfaces in `:analytics:api` --- .../watchers/NoopAnalyticsColdStartWatcher.kt | 19 +++++++++++++++++++ .../NoopAnalyticsRoomListStateWatcher.kt | 18 ++++++++++++++++++ 2 files changed, 37 insertions(+) create mode 100644 services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/watchers/NoopAnalyticsColdStartWatcher.kt create mode 100644 services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/watchers/NoopAnalyticsRoomListStateWatcher.kt diff --git a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/watchers/NoopAnalyticsColdStartWatcher.kt b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/watchers/NoopAnalyticsColdStartWatcher.kt new file mode 100644 index 0000000000..c24c98ebfe --- /dev/null +++ b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/watchers/NoopAnalyticsColdStartWatcher.kt @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.services.analytics.noop.watchers + +import dev.zacsweers.metro.AppScope +import dev.zacsweers.metro.ContributesBinding +import io.element.android.services.analytics.api.watchers.AnalyticsColdStartWatcher + +@ContributesBinding(AppScope::class) +class NoopAnalyticsColdStartWatcher : AnalyticsColdStartWatcher { + override fun start() {} + override fun whenLoggingIn() {} + override fun onRoomListVisible() {} +} diff --git a/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/watchers/NoopAnalyticsRoomListStateWatcher.kt b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/watchers/NoopAnalyticsRoomListStateWatcher.kt new file mode 100644 index 0000000000..711947fb2c --- /dev/null +++ b/services/analytics/noop/src/main/kotlin/io/element/android/services/analytics/noop/watchers/NoopAnalyticsRoomListStateWatcher.kt @@ -0,0 +1,18 @@ +/* + * Copyright (c) 2025 Element Creations Ltd. + * + * SPDX-License-Identifier: AGPL-3.0-only OR LicenseRef-Element-Commercial. + * Please see LICENSE files in the repository root for full details. + */ + +package io.element.android.services.analytics.noop.watchers + +import dev.zacsweers.metro.ContributesBinding +import io.element.android.libraries.di.SessionScope +import io.element.android.services.analytics.api.watchers.AnalyticsRoomListStateWatcher + +@ContributesBinding(SessionScope::class) +class NoopAnalyticsRoomListStateWatcher : AnalyticsRoomListStateWatcher { + override fun start() {} + override fun stop() {} +} From c6e0686dec287b0083cce49ffd16d7dc1df37021 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Fri, 28 Nov 2025 08:22:36 +0100 Subject: [PATCH 098/113] Reuse coroutine in `DefaultAnalyticsRoomListStateWatcher` instead of creating and cancelling the same one --- .../DefaultAnalyticsRoomListStateWatcher.kt | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt index cd1af657b2..97e438fcee 100644 --- a/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt +++ b/services/analytics/impl/src/main/kotlin/io/element/android/services/analytics/impl/watchers/DefaultAnalyticsRoomListStateWatcher.kt @@ -20,7 +20,7 @@ import io.element.android.services.analytics.api.finishLongRunningTransaction import io.element.android.services.analytics.api.watchers.AnalyticsRoomListStateWatcher import io.element.android.services.appnavstate.api.AppNavigationStateService import kotlinx.coroutines.CoroutineScope -import kotlinx.coroutines.cancel +import kotlinx.coroutines.cancelChildren import kotlinx.coroutines.flow.distinctUntilChanged import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.map @@ -33,19 +33,19 @@ class DefaultAnalyticsRoomListStateWatcher( private val appNavigationStateService: AppNavigationStateService, private val roomListService: RoomListService, private val analyticsService: AnalyticsService, - @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, - private val dispatchers: CoroutineDispatchers, + @SessionCoroutineScope sessionCoroutineScope: CoroutineScope, + dispatchers: CoroutineDispatchers, ) : AnalyticsRoomListStateWatcher { - private var currentCoroutineScope: CoroutineScope? = null + private val coroutineScope: CoroutineScope = sessionCoroutineScope.childScope(dispatchers.computation, "AnalyticsRoomListStateWatcher") + private val isStarted = AtomicBoolean(false) private val isWarmState = AtomicBoolean(false) override fun start() { - if (currentCoroutineScope != null) { + if (isStarted.getAndSet(true)) { Timber.w("Can't start RoomListStateWatcher, it's already running.") return } - val coroutineScope = sessionCoroutineScope.childScope(dispatchers.computation, "AnalyticsRoomListStateWatcher") appNavigationStateService.appNavigationState .map { it.isInForeground } .distinctUntilChanged() @@ -68,12 +68,11 @@ class DefaultAnalyticsRoomListStateWatcher( } } .launchIn(coroutineScope) - - currentCoroutineScope = coroutineScope } override fun stop() { - currentCoroutineScope?.cancel() - currentCoroutineScope = null + if (isStarted.getAndSet(false)) { + coroutineScope.coroutineContext.cancelChildren() + } } } From f265a47243157c9abc769a65905658571cd3e688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Fri, 28 Nov 2025 08:25:26 +0100 Subject: [PATCH 099/113] Make sure we don't finish `NotificationTapOpensTimeline` until we've actually rendered the timeline event we need to focus on --- .../features/messages/impl/timeline/TimelinePresenter.kt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt index 127dab0345..7b8ff837c1 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt @@ -206,6 +206,9 @@ class TimelinePresenter( focusOnEvent(event.eventId, focusRequestState) }.start() is TimelineEvents.OnFocusEventRender -> { + // If there was a pending 'notification tap opens timeline' transaction, finish it now we're focused in the required event + analyticsService.finishLongRunningTransaction(NotificationTapOpensTimeline) + focusRequestState.value = focusRequestState.value.onFocusEventRender() } is TimelineEvents.ClearFocusRequestState -> { @@ -242,7 +245,6 @@ class TimelinePresenter( analyticsService.run { finishLongRunningTransaction(DisplayFirstTimelineItems) finishLongRunningTransaction(OpenRoom) - finishLongRunningTransaction(NotificationTapOpensTimeline) } } .launchIn(this) From 32d56ea92db68d82a45f701c2a3e2fc89e1a4102 Mon Sep 17 00:00:00 2001 From: bmarty <3940906+bmarty@users.noreply.github.com> Date: Mon, 1 Dec 2025 00:23:54 +0000 Subject: [PATCH 100/113] Sync Strings from Localazy --- .../src/main/res/values-it/translations.xml | 11 + .../main/res/values-pt-rBR/translations.xml | 11 + .../src/main/res/values-zh/translations.xml | 6 + .../src/main/res/values-fi/translations.xml | 2 +- .../main/res/values-pt-rBR/translations.xml | 1 + .../src/main/res/values-fa/translations.xml | 1 + .../src/main/res/values-it/translations.xml | 2 + .../main/res/values-pt-rBR/translations.xml | 3 + .../src/main/res/values-uz/translations.xml | 4 + .../src/main/res/values-zh/translations.xml | 2 + .../src/main/res/values-uz/translations.xml | 6 + .../src/main/res/values-it/translations.xml | 13 +- .../main/res/values-pt-rBR/translations.xml | 13 +- .../src/main/res/values-uz/translations.xml | 14 + .../src/main/res/values-zh/translations.xml | 12 +- .../src/main/res/values-uz/translations.xml | 31 + .../src/main/res/values-uz/translations.xml | 3 + .../src/main/res/values-fa/translations.xml | 8 + .../src/main/res/values-uz/translations.xml | 1 + .../src/main/res/values-uz/translations.xml | 10 + .../src/main/res/values-fa/translations.xml | 1 + .../src/main/res/values-fa/translations.xml | 4 + .../src/main/res/values-it/translations.xml | 2 + .../main/res/values-pt-rBR/translations.xml | 5 + .../src/main/res/values-uz/translations.xml | 22 + .../src/main/res/values-uz/translations.xml | 4 + .../src/main/res/values-uz/translations.xml | 1 + .../src/main/res/values-it/translations.xml | 6 + .../main/res/values-pt-rBR/translations.xml | 13 + .../src/main/res/values-uz/translations.xml | 16 + .../src/main/res/values-zh/translations.xml | 4 + .../src/main/res/values-it/translations.xml | 2 + .../main/res/values-pt-rBR/translations.xml | 2 + .../src/main/res/values-uz/translations.xml | 1 + .../src/main/res/values-uz/translations.xml | 4 + .../src/main/res/values-cs/translations.xml | 33 +- .../src/main/res/values-fa/translations.xml | 4 + .../src/main/res/values-fi/translations.xml | 16 +- .../src/main/res/values-fr/translations.xml | 15 +- .../src/main/res/values-it/translations.xml | 35 +- .../main/res/values-pt-rBR/translations.xml | 31 +- .../src/main/res/values-uz/translations.xml | 8 + .../src/main/res/values-zh/translations.xml | 3 +- .../src/main/res/values-uz/translations.xml | 1 + .../src/main/res/values-bg/translations.xml | 2 +- .../src/main/res/values-cs/translations.xml | 65 +- .../src/main/res/values-cy/translations.xml | 2 +- .../src/main/res/values-da/translations.xml | 2 +- .../src/main/res/values-de/translations.xml | 2 +- .../src/main/res/values-el/translations.xml | 2 +- .../src/main/res/values-es/translations.xml | 2 +- .../src/main/res/values-et/translations.xml | 2 +- .../src/main/res/values-eu/translations.xml | 2 +- .../src/main/res/values-fa/translations.xml | 6 +- .../src/main/res/values-fi/translations.xml | 44 +- .../src/main/res/values-fr/translations.xml | 18 +- .../src/main/res/values-hu/translations.xml | 2 +- .../src/main/res/values-in/translations.xml | 2 +- .../src/main/res/values-it/translations.xml | 64 +- .../src/main/res/values-ko/translations.xml | 2 +- .../src/main/res/values-nb/translations.xml | 2 +- .../src/main/res/values-pl/translations.xml | 2 +- .../main/res/values-pt-rBR/translations.xml | 60 +- .../src/main/res/values-pt/translations.xml | 2 +- .../src/main/res/values-ro/translations.xml | 2 +- .../src/main/res/values-ru/translations.xml | 2 +- .../src/main/res/values-sk/translations.xml | 2 +- .../src/main/res/values-sv/translations.xml | 2 +- .../src/main/res/values-tr/translations.xml | 2 +- .../src/main/res/values-uk/translations.xml | 2 +- .../src/main/res/values-uz/translations.xml | 37 + .../main/res/values-zh-rTW/translations.xml | 2 +- .../src/main/res/values-zh/translations.xml | 4 +- .../impl/src/main/res/values/localazy.xml | 6 +- .../src/main/res/values-cs/translations.xml | 2 + .../src/main/res/values-fi/translations.xml | 4 +- .../src/main/res/values-it/translations.xml | 4 +- .../main/res/values-pt-rBR/translations.xml | 4 +- .../src/main/res/values-uz/translations.xml | 5 + .../src/main/res/values-zh/translations.xml | 4 +- .../src/main/res/values-be/translations.xml | 3 +- .../src/main/res/values-bg/translations.xml | 11 +- .../src/main/res/values-cs/translations.xml | 37 +- .../src/main/res/values-cy/translations.xml | 16 +- .../src/main/res/values-da/translations.xml | 16 +- .../src/main/res/values-de/translations.xml | 16 +- .../src/main/res/values-el/translations.xml | 15 +- .../src/main/res/values-es/translations.xml | 16 +- .../src/main/res/values-et/translations.xml | 27 +- .../src/main/res/values-eu/translations.xml | 12 +- .../src/main/res/values-fa/translations.xml | 12 +- .../src/main/res/values-fi/translations.xml | 35 +- .../src/main/res/values-fr/translations.xml | 62 +- .../src/main/res/values-hu/translations.xml | 27 +- .../src/main/res/values-in/translations.xml | 16 +- .../src/main/res/values-it/translations.xml | 35 +- .../src/main/res/values-ko/translations.xml | 16 +- .../src/main/res/values-nb/translations.xml | 16 +- .../src/main/res/values-nl/translations.xml | 3 +- .../src/main/res/values-pl/translations.xml | 18 +- .../main/res/values-pt-rBR/translations.xml | 38 +- .../src/main/res/values-pt/translations.xml | 14 +- .../src/main/res/values-ro/translations.xml | 16 +- .../src/main/res/values-ru/translations.xml | 25 +- .../src/main/res/values-sk/translations.xml | 16 +- .../src/main/res/values-sv/translations.xml | 15 +- .../src/main/res/values-tr/translations.xml | 18 +- .../src/main/res/values-uk/translations.xml | 18 +- .../src/main/res/values-uz/translations.xml | 30 +- .../main/res/values-zh-rTW/translations.xml | 35 +- .../src/main/res/values-zh/translations.xml | 16 +- .../impl/src/main/res/values/localazy.xml | 24 +- .../src/main/res/values-cs/translations.xml | 2 +- .../src/main/res/values-it/translations.xml | 11 + .../main/res/values-pt-rBR/translations.xml | 11 + .../src/main/res/values-uz/translations.xml | 1 + .../src/main/res/values-uz/translations.xml | 6 + .../main/res/values-pt-rBR/translations.xml | 6 +- .../src/main/res/values-uz/translations.xml | 12 + .../src/main/res/values-zh/translations.xml | 6 +- .../src/main/res/values-uz/translations.xml | 4 + .../src/main/res/values-uz/translations.xml | 3 + .../src/main/res/values-uz/translations.xml | 21 + .../src/main/res/values-cs/translations.xml | 1 + .../src/main/res/values-fa/translations.xml | 24 + .../src/main/res/values-fi/translations.xml | 1 + .../src/main/res/values-it/translations.xml | 13 + .../main/res/values-pt-rBR/translations.xml | 13 + .../src/main/res/values-uz/translations.xml | 2 + .../src/main/res/values-zh/translations.xml | 8 + .../src/main/res/values-uz/translations.xml | 7 + .../src/main/res/values-uz/translations.xml | 1 + .../src/main/res/values-cs/translations.xml | 4 + .../src/main/res/values-fa/translations.xml | 18 +- .../src/main/res/values-fi/translations.xml | 7 +- .../src/main/res/values-it/translations.xml | 27 +- .../main/res/values-pt-rBR/translations.xml | 46 +- .../src/main/res/values-uz/translations.xml | 76 +- .../src/main/res/values-zh/translations.xml | 7 + .../src/main/res/values/localazy.xml | 7 + screenshots/html/data.js | 1873 +++++++++-------- 141 files changed, 2195 insertions(+), 1453 deletions(-) create mode 100644 features/announcement/impl/src/main/res/values-it/translations.xml create mode 100644 features/announcement/impl/src/main/res/values-pt-rBR/translations.xml create mode 100644 libraries/mediaviewer/impl/src/main/res/values-uz/translations.xml diff --git a/features/announcement/impl/src/main/res/values-it/translations.xml b/features/announcement/impl/src/main/res/values-it/translations.xml new file mode 100644 index 0000000000..584ddcdf21 --- /dev/null +++ b/features/announcement/impl/src/main/res/values-it/translations.xml @@ -0,0 +1,11 @@ + + + "Visualizza gli spazi che hai creato o a cui partecipi" + "Accetta o rifiuta gli inviti agli spazi" + "Scopri tutte le stanze a cui puoi partecipare nei tuoi spazi" + "Unisciti agli spazi pubblici" + "Lascia tutti gli spazi a cui ti sei unito" + "A breve saranno disponibili le funzionalità di filtraggio, creazione e gestione degli spazi." + "Benvenuti alla versione beta degli Spazi! Con questa prima versione potrete:" + "Ti presentiamo gli Spazi" + diff --git a/features/announcement/impl/src/main/res/values-pt-rBR/translations.xml b/features/announcement/impl/src/main/res/values-pt-rBR/translations.xml new file mode 100644 index 0000000000..32a9bf85af --- /dev/null +++ b/features/announcement/impl/src/main/res/values-pt-rBR/translations.xml @@ -0,0 +1,11 @@ + + + "Visualizar espaços que criou ou entrou" + "Aceitar ou recusar convites aos espaços" + "Descobrir quaisquer salas que você pode entrar nos espaços" + "Entrar espaços públicos" + "Sair de quaisquer espaços que entrou" + "Filtrar, criar, e gerenciar espaços virão em breve." + "Boas-vindas à versão beta dos Espaços! Com essa primeira versão, você pode:" + "Apresentando Espaços" + diff --git a/features/announcement/impl/src/main/res/values-zh/translations.xml b/features/announcement/impl/src/main/res/values-zh/translations.xml index 66608eb6e5..e01e63b2ae 100644 --- a/features/announcement/impl/src/main/res/values-zh/translations.xml +++ b/features/announcement/impl/src/main/res/values-zh/translations.xml @@ -2,4 +2,10 @@ "查看您创建或加入的空间" "接受或拒绝空间邀请" + "发现您可以加入空间的所有房间" + "加入公共空间" + "离开你加入的所有空间" + "筛选、创建及管理空间功能即将上线。" + "欢迎使用 Spaces 测试版!使用首个版本,您可以:" + "Spaces 简介" diff --git a/features/createroom/impl/src/main/res/values-fi/translations.xml b/features/createroom/impl/src/main/res/values-fi/translations.xml index 31589ab997..df541d3dee 100644 --- a/features/createroom/impl/src/main/res/values-fi/translations.xml +++ b/features/createroom/impl/src/main/res/values-fi/translations.xml @@ -1,7 +1,7 @@ "Uusi huone" - "Kutsu ihmisiä" + "Kutsu henkilöitä" "Huoneen luomisessa tapahtui virhe" "Vain kutsutut henkilöt pääsevät tähän huoneeseen. Kaikki viestit ovat päästä päähän salattuja." "Yksityinen huone" diff --git a/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml b/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml index 73aaaa503e..399c9fec17 100644 --- a/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/createroom/impl/src/main/res/values-pt-rBR/translations.xml @@ -14,6 +14,7 @@ Você pode mudar isso a qualquer momento nas configurações da sala." "Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou moderador terá de aceitar a solicitação" "Pedir para entrar" "Para que esta sala fique visível no diretório público de salas, você precisará de um endereço de sala." + "Endereço da sala" "Nome da sala" "Visibilidade da sala" "Criar uma sala" diff --git a/features/home/impl/src/main/res/values-fa/translations.xml b/features/home/impl/src/main/res/values-fa/translations.xml index 7e3658e0eb..aec50309d8 100644 --- a/features/home/impl/src/main/res/values-fa/translations.xml +++ b/features/home/impl/src/main/res/values-fa/translations.xml @@ -6,6 +6,7 @@ "بازگردانی تاریخچهٔ پیام‌ها و هویت رمزنگاشته‌تان با کلید بازیابی در صورت از دست دادن همهٔ افزاره‌های موجودتان." "برپایی بازیابی" "برپایی بازیابی" + "کلید بازیابی خود را تأیید کنید تا دسترسی به حافظه کلیدها و تاریخچه پیام‌هایتان حفظ شود ." "ورود کلید بازیابیتان" "ذخیره‌ساز کلیدتان از هم‌گام بودن در آمده" "بهبود تجریهٔ تماستان" diff --git a/features/home/impl/src/main/res/values-it/translations.xml b/features/home/impl/src/main/res/values-it/translations.xml index 74f8d4abac..932545c7b0 100644 --- a/features/home/impl/src/main/res/values-it/translations.xml +++ b/features/home/impl/src/main/res/values-it/translations.xml @@ -3,6 +3,8 @@ "Disabilita l\'ottimizzazione della batteria per questa app, per assicurarti che tutte le notifiche vengano ricevute." "Disabilita l\'ottimizzazione" "Le notifiche non arrivano?" + "Il ping delle notifiche è stato aggiornato: ora è più chiaro, più rapido e meno fastidioso." + "Abbiamo rinnovato i tuoi suoni" "Recupera la tua identità crittografica e la cronologia dei messaggi con una chiave di recupero se hai perso tutti i tuoi dispositivi." "Configura il recupero" "Configura il ripristino" diff --git a/features/home/impl/src/main/res/values-pt-rBR/translations.xml b/features/home/impl/src/main/res/values-pt-rBR/translations.xml index 7aab508a38..10f5cf9585 100644 --- a/features/home/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/home/impl/src/main/res/values-pt-rBR/translations.xml @@ -3,6 +3,8 @@ "Desative a otimização de bateria para este app, para que tenha certeza que todas as notificações sejam recebidas." "Desativar otimização" "As notificações não chegam?" + "O seu ping de notificação foi atualizado—mais suave, mais rápido, e menos disruptivo." + "Recarregamos seus sons" "Recupere sua identidade criptográfica e o histórico de mensagens com uma chave de recuperação caso você perda todos os dispositivos existentes." "Configurar a recuperação" "Configure a recuperação para proteger sua conta" @@ -33,6 +35,7 @@ Por enquanto, você pode desmarcar os filtros para ver suas outras conversas""Convites" "Você não tem nenhum convite pendente." "Baixa prioridade" + "Você ainda não tem nenhuma conversa de baixa prioridade" "Você pode desmarcar filtros para ver suas outras conversas" "Você não tem conversas para esta seleção" "Pessoas" diff --git a/features/home/impl/src/main/res/values-uz/translations.xml b/features/home/impl/src/main/res/values-uz/translations.xml index fbfeca156a..2de9b1b266 100644 --- a/features/home/impl/src/main/res/values-uz/translations.xml +++ b/features/home/impl/src/main/res/values-uz/translations.xml @@ -13,6 +13,7 @@ "Muhim qoʻngʻiroqlarni oʻtkazib yubormasligingiz uchun telefoningiz qulflangan holatida toʻliq ekranli bildirishnomalarni ko‘rsatishga ruxsat beradigan qilib sozlamalaringizni oʻzgartiring." "Qoʻngʻiroq tajribangizni yaxshilang" "Suhbatlar" + "Bo‘shliqlar" "Haqiqatan ham qo\'shilish taklifini rad qilmoqchimisiz%1$s ?" "Taklifni rad etish" "Haqiqatan ham bu shaxsiy chatni rad qilmoqchimisiz%1$s ?" @@ -22,6 +23,7 @@ "Bu bir martalik jarayon, kutganingiz uchun rahmat." "Hisobingiz sozlanmoqda." "Yangi suhbat yoki xona yarating" + "Filtrlarni tozalash" "Kimgadir xabar yuborishdan boshlang." "Hozircha chatlar yo‘q." "Sevimlilar" @@ -31,6 +33,7 @@ Hozircha, boshqa suhbatlaringizni ko‘rish uchun filtrlarni bekor qilishingiz m "Takliflar" "Sizda hech qanday kutilayotgan takliflar yoʻq." "Past darajali" + "Sizda hali past ustuvor chatlar yoʻq" "Boshqa suhbatlaringizni koʻrish uchun filtrlarni bekor qilishingiz mumkin" "Sizda bu tanlov uchun chatlar yo‘q" "Odamlar" @@ -44,6 +47,7 @@ Sizda oʻqilmagan xabarlar yoʻq!" "Suhbatlar" "Oʻqilgan deb belgilash" "Oʻqilmagan deb belgilash" + "Bu xona yangilandi" "Siz yangi qurilmadan foydalanayotganga o‘xshaysiz. Shifrlangan xabarlaringizga kirish uchun boshqa qurilma bilan tasdiqlang." "Siz ekanligingizni tasdiqlang" diff --git a/features/home/impl/src/main/res/values-zh/translations.xml b/features/home/impl/src/main/res/values-zh/translations.xml index 805b56de5c..748159d80f 100644 --- a/features/home/impl/src/main/res/values-zh/translations.xml +++ b/features/home/impl/src/main/res/values-zh/translations.xml @@ -3,6 +3,8 @@ "请关闭本应用的电池优化设置,确保不错过任何消息通知。" "禁用优化" "通知未送达?" + "您的通知提示音已升级 - 更清晰、更快速、干扰更少。" + "我们已更新您的声音" "生成新的恢复密钥,该密钥可用于在您无法访问设备时恢复加密的消息历史记录。" "设置恢复" "设置恢复" diff --git a/features/invite/impl/src/main/res/values-uz/translations.xml b/features/invite/impl/src/main/res/values-uz/translations.xml index bdefbd31d3..ab20b58101 100644 --- a/features/invite/impl/src/main/res/values-uz/translations.xml +++ b/features/invite/impl/src/main/res/values-uz/translations.xml @@ -1,6 +1,9 @@ + "Siz bu foydalanuvchidan hech qanday xabar yoki xonaga taklif ko‘rmaysiz" "Foydalanuvchini bloklash" + "Bu xona haqida hisobingiz provayderiga xabar bering." + "Xabar berish sababini tushuntiring…" "Rad etish va bloklash" "Haqiqatan ham qo\'shilish taklifini rad qilmoqchimisiz%1$s ?" "Taklifni rad etish" @@ -8,5 +11,8 @@ "Chatni rad etish" "Takliflar yo\'q" "%1$s(%2$s ) sizni taklif qildi" + "Ha, rad etish va bloklash" + "Ushbu xonaga qo‘shilish taklifini rad etishga ishonchingiz komilmi? Bu %1$sning siz bilan bog‘lanishiga yoki sizni xonalarga taklif qilishiga ham to‘sqinlik qiladi." + "Taklifni rad etish va bloklash" "Rad etish va bloklash" diff --git a/features/joinroom/impl/src/main/res/values-it/translations.xml b/features/joinroom/impl/src/main/res/values-it/translations.xml index deb025db27..756d6edc40 100644 --- a/features/joinroom/impl/src/main/res/values-it/translations.xml +++ b/features/joinroom/impl/src/main/res/values-it/translations.xml @@ -1,7 +1,7 @@ - "Sei stato bandito da questa stanza da %1$s." - "Sei stato bandito da questa stanza" + "Sei stato bannato da %1$s ." + "Sei stato bannato" "Motivo: %1$s" "Cancella richiesta" "Sì, annulla" @@ -11,10 +11,11 @@ "Sei sicuro di voler rifiutare l\'invito a entrare in questa stanza? Ciò impedirà a %1$s di contattarti o invitarti nuovamente in una stanza." "Rifiuta invito e blocca" "Rifiuta e blocca" - "L\'accesso alla stanza non è riuscito." - "Questa stanza è solo su invito o potrebbero esserci delle restrizioni all\'accesso al livello dello spazio." - "Dimentica questa stanza" - "Hai bisogno di un invito per entrare in questa stanza" + "Partecipazione non riuscita" + "Devi essere invitato per partecipare o potrebbero esserci delle restrizioni di accesso." + "Dimentica" + "Per partecipare è necessario un invito" + "Invitato da" "Entra" "Potrebbe essere necessario essere invitati o essere membro di uno spazio per partecipare." "Bussa per partecipare" diff --git a/features/joinroom/impl/src/main/res/values-pt-rBR/translations.xml b/features/joinroom/impl/src/main/res/values-pt-rBR/translations.xml index ed553bd93a..247532946f 100644 --- a/features/joinroom/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/joinroom/impl/src/main/res/values-pt-rBR/translations.xml @@ -1,7 +1,7 @@ - "Você foi banido desta sala por %1$s." - "Você foi banido desta sala" + "Você foi banido por %1$s." + "Você foi banido" "Motivo: %1$s." "Cancelar pedido" "Sim, cancelar" @@ -11,10 +11,11 @@ "Tem certeza de que quer recusar o convite para entrar nesta sala? Isso também impedirá que %1$s entre em contato com você ou o convide para salas." "Recusar convite e bloquear" "Recusar e bloquear" - "A entrada na sala falhou." - "Esta sala é apenas para convidados ou pode haver restrições de acesso a nível do espaço." - "Esquecer esta sala" - "Você precisa de um convite para entrar nesta sala" + "Falha ao entrar" + "Você precisa ser convidado ou pode haver restrições ao acesso." + "Esquecer" + "Você precisa de um convite para entrar" + "Convidado por" "Entrar" "Talvez você precise ser convidado ou ser membro de um espaço para participar." "Enviar solicitação para entrar" diff --git a/features/joinroom/impl/src/main/res/values-uz/translations.xml b/features/joinroom/impl/src/main/res/values-uz/translations.xml index e8c50922c4..de8b10f2b1 100644 --- a/features/joinroom/impl/src/main/res/values-uz/translations.xml +++ b/features/joinroom/impl/src/main/res/values-uz/translations.xml @@ -1,15 +1,29 @@ + "Siz %1$s tomonidan ushbu xonadan ban qilingansiz." + "Siz bu xonadan chetlashtirilgansiz" + "Sababi: %1$s ." "So‘rovni bekor qilish" "Ha, bekor qiling" "Bu xonaga qo‘shilish so‘rovingizni bekor qilishni xohlayotganingizga ishonchingiz komilmi?" "Qo‘shilish so‘rovini bekor qilish" + "Ha, rad etish va bloklash" + "Ushbu xonaga qo‘shilish taklifini rad etishga ishonchingiz komilmi? Bu %1$sning siz bilan bog‘lanishiga yoki sizni xonalarga taklif qilishiga ham to‘sqinlik qiladi." + "Taklifni rad etish va bloklash" "Rad etish va bloklash" + "Xonaga qo‘shilish amalga oshmadi" + "Bu xona faqat taklif etilganlar uchun yoki bu maydonga kirish huquqi cheklangan bo‘lishi mumkin." + "Bu xonani esdan chiqarish" + "Bu xonaga kirish uchun taklifnoma kerak" "Qo\'shilish" + "Qo‘shilish uchun sizga taklif kerak yoki siz maydonga a’zo bo‘lishingiz kerak." "Qoʻshilish soʻrovini yuborish" + "Ruxsat etilgan belgilar: %1$d / %2$d" "Xabar (ixtiyoriy)" "Agar so‘rovingiz qabul qilinsa, xonaga qo‘shilish taklifini olasiz." "Qo‘shilish so‘rovi yuborildi" + "Xona ko‘rinishini namoyish eta olmadik. Bu tarmoq yoki server muammolari tufayli yuz bergan bo‘lishi mumkin." + "Biz bu xonani oldindan ko‘rishni ko‘rsata olmadik " "%1$s hali maydon xizmatini qoʻllab-quvvatlamaydi. maydonga veb-sayt orqali kirishingiz mumkin." "Maydonlar hali qoʻllab-quvvatlanmaydi" "Quyidagi tugmani bosing va xona administratoriga xabar beriladi. Ruxsat berilgandan soʻng suhbatga qoʻshilishingiz mumkin boʻladi." diff --git a/features/joinroom/impl/src/main/res/values-zh/translations.xml b/features/joinroom/impl/src/main/res/values-zh/translations.xml index 52361e01aa..7bea362c81 100644 --- a/features/joinroom/impl/src/main/res/values-zh/translations.xml +++ b/features/joinroom/impl/src/main/res/values-zh/translations.xml @@ -1,7 +1,7 @@ - "你被 %1$s 从此房间封禁。" - "你已被此房间封禁" + "您已被禁止访问%1$s。" + "你已被禁止访问" "理由:%1$s。" "取消请求" "是的,取消" @@ -11,10 +11,10 @@ "您确定要拒绝加入此房间的邀请吗?这也将阻止%1$s 与您联系或邀请您加入房间。" "拒绝邀请并屏蔽" "拒绝并屏蔽" - "加入房间失败。" - "要么此房间仅限受邀者,要么可能在空间层级有加入限制。" - "忘记这个房间" - "你需要邀请才能加入这个房间" + "加入失败" + "您需要被邀请加入,否则可能会受到访问限制。" + "忘记" + "您需要邀请才能加入" "受邀于" "加入" "您可能需要受到邀请或成为某个空间的成员才能加入。" diff --git a/features/knockrequests/impl/src/main/res/values-uz/translations.xml b/features/knockrequests/impl/src/main/res/values-uz/translations.xml index 8cad1166df..24d8fb3fac 100644 --- a/features/knockrequests/impl/src/main/res/values-uz/translations.xml +++ b/features/knockrequests/impl/src/main/res/values-uz/translations.xml @@ -1,5 +1,36 @@ + "Ha, hammasini qabul qiling" + "Barcha qo‘shilish so‘rovlarini qabul qilishga ishonchingiz komilmi?" + "Barcha so‘rovlarni qabul qilish" + "Hammasini qabul qiling" + "Biz barcha so‘rovlarni qabul qila olmadik. Qayta urinib koʻrmoqchimisiz?" + "Barcha so‘rovlar qabul qilinmadi" + "Qo‘shilish so‘rovi qabul qilinmoqda" + "Biz bu so‘rovni qabul qila olmadik. Yana bir bor urinib ko‘rishni xohlaysizmi?" + "So‘rovni qabul qilib bo‘lmadi" + "Qo‘shilish so‘rovi qabul qilinmoqda" + "Ha, rad eting va taqiqlang" + "Siz %1$sʼni rad etib, taqiqlashni xohlayotganingizga ishonchingiz komilmi? Bu foydalanuvchi ushbu xonaga qayta kirish uchun ruxsat so‘ray olmaydi." + "Rad etish va kirishni taqiqlash" + "Kirishni rad etish va taqiqlash" + "Ha, rad etish" + "%1$sning bu xonaga qo‘shilish so‘rovini rad etasizmi?" + "Kirishni rad etish" + "Rad etish va taqiqlash" + "Biz bu iltimosni rad etolmasdik. Yana bir bor urinib ko‘rishni xohlaysizmi?" + "So‘rovni rad etib bo‘lmadi" + "Qo‘shilish so‘rovi rad etilayapti" + "Kimdir xonaga qo‘shilishni so‘raganda, uning iltimosini shu yerda ko‘rishingiz mumkin." + "Qo‘shilish so‘rovi kutilmayapti" + "Qo‘shilish uchun so‘rovlar yuklanmoqda…" + "Qo‘shilish uchun so‘rovlar" + + "%1$s + %2$d kishi bu xonaga qo‘shilmoqchi" + "%1$s + %2$d kishi bu xonaga qo‘shilmoqchi" + + "Hammasini ko\'rish" "Qabul qiling" + "%1$s bu xonaga qo‘shilmoqchi" "Ko\'rish" diff --git a/features/leaveroom/api/src/main/res/values-uz/translations.xml b/features/leaveroom/api/src/main/res/values-uz/translations.xml index 374fd347fc..e04bbf4b7f 100644 --- a/features/leaveroom/api/src/main/res/values-uz/translations.xml +++ b/features/leaveroom/api/src/main/res/values-uz/translations.xml @@ -3,5 +3,8 @@ "Bu suhbatni tark etmoqchi ekanligingizga ishonchingiz komilmi? Bu suhbat hammaga ochiq emas va siz taklifsiz qayta qo‘shila olmaysiz." "Bu xonani tark etmoqchi ekanligingizga ishonchingiz komilmi? Siz bu yerda yagona odamsiz. Agar siz tark etsangiz, kelajakda hech kim qo\'shila olmaydi, jumladan siz ham." "Bu xonani tark etmoqchi ekanligingizga ishonchingiz komilmi? Bu xona ochiq emas va siz taklifsiz qayta qo‘shila olmaysiz." + "Egalarni tanlang" + "Siz bu xonaning yagona egasisiz. Xonadan chiqishdan oldin egalikni boshqaga topshirishingiz kerak." + "Egalikni topshirish" "Xonani tark etmoqchi ekanligingizga ishonchingiz komilmi?" diff --git a/features/lockscreen/impl/src/main/res/values-fa/translations.xml b/features/lockscreen/impl/src/main/res/values-fa/translations.xml index 8e57ec8d68..56dc91e835 100644 --- a/features/lockscreen/impl/src/main/res/values-fa/translations.xml +++ b/features/lockscreen/impl/src/main/res/values-fa/translations.xml @@ -24,6 +24,14 @@ "پین‌ها مطابق نیستند" "برای ادامه باید دوباره وارد شده و پینی جدید ایجاد کنید" "دارید خارج می‌شوید" + + "شما %1$d تلاش برای باز کردن قفل دارید" + "شما %1$d تلاش برای باز کردن قفل دارید" + + + "پین اشتباه است. شما %1$d شانس دیگر دارید" + "پین اشتباه است. شما %1$d شانس دیگر دارید" + "استفاده از زیست‌سنجی" "استفاده از پین" "خارج شدن…" diff --git a/features/lockscreen/impl/src/main/res/values-uz/translations.xml b/features/lockscreen/impl/src/main/res/values-uz/translations.xml index 9981cf3bce..8cd0a57b94 100644 --- a/features/lockscreen/impl/src/main/res/values-uz/translations.xml +++ b/features/lockscreen/impl/src/main/res/values-uz/translations.xml @@ -3,6 +3,7 @@ "biometrik autentifikatsiya" "biometrik qulf ochish" "Biometrik bilan qulfni oching" + "Biometrikni tasdiqlang" "PIN kodni unutdingizmi?" "PIN kodni o\'zgartirish" "Biometrik qulfni ochishga ruxsat bering" diff --git a/features/login/impl/src/main/res/values-uz/translations.xml b/features/login/impl/src/main/res/values-uz/translations.xml index 373081f3c3..9c6c297b20 100644 --- a/features/login/impl/src/main/res/values-uz/translations.xml +++ b/features/login/impl/src/main/res/values-uz/translations.xml @@ -13,9 +13,17 @@ "Boshqa" "Shaxsiy serveringiz yoki ishchi hisob qaydnomangiz kabi boshqa hisob provayderidan foydalaning." "Hisob provayderini o\'zgartiring" + "Google Play" + "%1$s da Element Pro ilovasi talab qilinadi. Iltimos, do‘kondan yuklab oling." + "Element Pro talab qilinadi" "Bu uy serveriga kira olmadik. Iltimos, uy serverining URL manzilini to\'ri kiritganingizni tekshiring. Agar URL toʻgʻri boʻlsa, qoʻshimcha yordam olish uchun uy serveri administratoriga murojaat qiling." ".well-known faylidagi muammo tufayli server mavjud emas: %1$s" + "Tanlangan hisob provayderi siljitish sinxronizatsiyasini qo‘llab-quvvatlamaydi. %1$s ishlatish uchun serverni yangilash zarur." + "%1$s uchun %2$s bilan ulanishga ruxsat berilmagan." + "Bu ilova quyidagilarga ruxsat berish uchun sozlangan: %1$s ." + "Hisob provayderi %1$s ga ruxsat berilmagan." "Uy serverining URL manzili" + "Domen manzilini kiriting." "Serveringizning manzili nima?" "Serveringizni tanlang" "Hisob yaratish" @@ -28,6 +36,7 @@ "Matrix xavfsiz, markazlashmagan aloqa uchun ochiq tarmoqdir." "Qaytib kelganingizdan xursandmiz!" "Kirish%1$s" + "%1$s versiya" "Qo\'lda tizimga kiring" "Kirish%1$s" "QR kod bilan tizimga kiring" @@ -83,5 +92,6 @@ Oddiy usulda kiring yoki boshqa qurilma bilan QR kodni skanerlang." "Matrix xavfsiz, markazlashmagan aloqa uchun ochiq tarmoqdir." "Bu sizning suhbatlaringiz yashaydigan joy - xuddi siz elektron pochta xabarlaringizni saqlash uchun elektron pochta provayderidan foydalanganingiz kabi." "Siz tizimga kirmoqchisiz%1$s" + "Hisob provayderini tanlang" "Hisob yaratmoqchisiz%1$s" diff --git a/features/logout/impl/src/main/res/values-fa/translations.xml b/features/logout/impl/src/main/res/values-fa/translations.xml index c4c6e823d0..8dfaad8580 100644 --- a/features/logout/impl/src/main/res/values-fa/translations.xml +++ b/features/logout/impl/src/main/res/values-fa/translations.xml @@ -6,6 +6,7 @@ "خارج شدن…" "دارید از واپسین نشستتان خارج می‌شوید. اگر اکنون خارج شوید پیام‌های رمزنگاشته‌تان را از دست خواهید داد." "پشتیبان را خاموش کرده‌اید" + "در هنگامی که آفلاین شدید، کلیدهای شما هنوز در حال پشتیبان‌گیری بودند. دوباره متصل شوید ، تا قبل از خروج از کلیدهایتان نسخه پشتیبان‌ گرفته شود." "کلیدهایتان هنوز در حال پشتیبان گیریند" "لطفاً پیش از خروج منتظر پایانش شوید." "کلیدهایتان هنوز در حال پشتیبان گیریند" diff --git a/features/messages/impl/src/main/res/values-fa/translations.xml b/features/messages/impl/src/main/res/values-fa/translations.xml index 56913e2f19..b102f82a98 100644 --- a/features/messages/impl/src/main/res/values-fa/translations.xml +++ b/features/messages/impl/src/main/res/values-fa/translations.xml @@ -42,6 +42,10 @@ "نمایش بیش‌تر" "نمایش خلاصهٔ واکنش‌ها" "جدید" + + "%1$dتغییر اتاق" + "%1$dتغییر اتاق" + "پرش به اتاق جدید" "این اتاق جایگزین شده و دیگر فعّال نیست" "دیدن پیام‌های قدیمی" diff --git a/features/messages/impl/src/main/res/values-it/translations.xml b/features/messages/impl/src/main/res/values-it/translations.xml index 87a7a05c93..c5b98c8178 100644 --- a/features/messages/impl/src/main/res/values-it/translations.xml +++ b/features/messages/impl/src/main/res/values-it/translations.xml @@ -7,6 +7,7 @@ "Oggetti" "Faccine & Persone" "Viaggi & Luoghi" + "Emoji recenti" "Simboli" "Le didascalie potrebbero non essere visibili agli utenti di app meno recenti." "Tocca per modificare la qualità di caricamento del video" @@ -15,6 +16,7 @@ "Caricamento del file multimediale fallito, riprova." "La dimensione massima consentita del file è %1$s ." "Il file è troppo grande per essere caricato" + "Elemento %1$d di %2$d" "Ottimizza la qualità delle immagini" "Elaborazione…" "Blocca utente" diff --git a/features/messages/impl/src/main/res/values-pt-rBR/translations.xml b/features/messages/impl/src/main/res/values-pt-rBR/translations.xml index c85f17bdb3..6098fd0889 100644 --- a/features/messages/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/messages/impl/src/main/res/values-pt-rBR/translations.xml @@ -7,13 +7,18 @@ "Objetos" "Sorrisos & Pessoas" "Viagens & Lugares" + "Emojis recentes" "Símbolos" "As legendas podem não ser visíveis para pessoas que usam apps mais antigos." + "Toque para alterar a qualidade do envio do vídeo" "O arquivo não pôde ser enviado." "Falha ao processar a mídia para o envio. Tente novamente." "Falha ao enviar mídia. Tente novamente." "O tamanho de arquivo máximo permitido é %1$s." "O arquivo é muito grande para enviar" + "%1$d de %2$d itens" + "Otimizar qualidade da imagem" + "Processando…" "Bloquear usuário" "Marque se você deseja ocultar todas as mensagens atuais e futuras desse usuário" "Essa mensagem será reportada ao administrador do seu servidor-casa. Eles não conseguirão ler nenhuma mensagem criptografada." diff --git a/features/messages/impl/src/main/res/values-uz/translations.xml b/features/messages/impl/src/main/res/values-uz/translations.xml index e48de2b6ad..8f75212a31 100644 --- a/features/messages/impl/src/main/res/values-uz/translations.xml +++ b/features/messages/impl/src/main/res/values-uz/translations.xml @@ -8,8 +8,15 @@ "Smayllar va odamlar" "Sayohat va Joylar" "Belgilar" + "Taglavhalar eski ilovalardan foydalanuvchilarga ko‘rinmasligi mumkin." + "Video yuklash sifatini oʻzgartirish uchun bosing" + "Faylni yuklab boʻlmadi." "Mediani yuklab bo‘lmadi, qayta urinib ko‘ring." "Media yuklanmadi, qayta urinib ko‘ring." + "Ruxsat etilgan maksimal fayl hajmi %1$s ." + "Fayl yuklash uchun juda katta" + "Tasvir sifatini optimallashtirish" + "Qayta ishlanmoqda…" "Foydalanuvchini bloklash" "Ushbu foydalanuvchidan barcha joriy va kelajakdagi xabarlarni yashirishni xohlayotganingizni tekshiring" "Bu xabar uy serveringiz administratoriga xabar qilinadi. Ular hech qanday shifrlangan xabarlarni o\'qiy olmaydi." @@ -33,16 +40,31 @@ "Emoji qo\'shmoq" "Bu %1$sni boshlanishi" "Bu suhbatning boshlanishi." + "Chaqiruv qabul qilinmaydi. Chaqiruvchidan yangi Element X ilovasidan foydalanishi mumkinligini so‘rang." "Kamroq ko\'rsatish" "Xabar nusxalandi" "Sizda bu xonaga post yozishga ruxsat yo‘q" + + "%1$d ta a’zo %2$s bilan munosabat bildirdi" + "%1$d ta a’zo %2$s bilan munosabat bildirdi" + + + "Siz va %1$d ta a’zo %2$s bilan munosabat bildirdi" + "Siz va %1$d ta a’zo %2$s bilan munosabat bildirdi" + + "%1$s bilan munosabat bildirdingiz" "Kamroq ko\'rsatish" "Ko\'proq ko\'rsatish" + "Reaksiyalar xulosasini chiqarish" "Yangi" "%1$dxonani almashtirish" "%1$dxona o\'zgarishi" + "Yangi xonaga o‘tish" + "Bu room almashtirildi va endi faol emas" + "Eski xabarlarni ko‘rish" + "Bu xona boshqa xonaning davomi" "%1$s, %2$s va %3$d boshqalar" "%1$s, %2$s va %3$d boshqalar" diff --git a/features/poll/api/src/main/res/values-uz/translations.xml b/features/poll/api/src/main/res/values-uz/translations.xml index 6e1a16a013..8446135f20 100644 --- a/features/poll/api/src/main/res/values-uz/translations.xml +++ b/features/poll/api/src/main/res/values-uz/translations.xml @@ -1,5 +1,9 @@ + + "Jami ovozlarning %1$d foizi" + "Jami ovozlarning %1$d foizi" + "Oldingi tanlov olib tashlanadi" "Bu g\'alaba qozongan javob" diff --git a/features/poll/impl/src/main/res/values-uz/translations.xml b/features/poll/impl/src/main/res/values-uz/translations.xml index 8ea1c4b827..28f496f3dd 100644 --- a/features/poll/impl/src/main/res/values-uz/translations.xml +++ b/features/poll/impl/src/main/res/values-uz/translations.xml @@ -5,6 +5,7 @@ "Ovozlarni yashirish" "Variant%1$d" "Oʻzgarishlar saqlanmadi. Haqiqatan ham orqaga qaytmoqchimisiz?" + "%1$s variantini o‘chirish" "Savol yoki mavzu" "So\'rovnoma nima haqida?" "So‘rovnoma yaratish" diff --git a/features/preferences/impl/src/main/res/values-it/translations.xml b/features/preferences/impl/src/main/res/values-it/translations.xml index 0a37b0d394..a10dcc9594 100644 --- a/features/preferences/impl/src/main/res/values-it/translations.xml +++ b/features/preferences/impl/src/main/res/values-it/translations.xml @@ -10,6 +10,7 @@ "URL non valido, assicurati di includere il protocollo (http/https) e l\'indirizzo corretto." "Nascondi gli avatar nelle richieste di invito alle stanze" "Nascondi le anteprime dei media nelle conversazioni" + "Labs" "Carica foto e video più velocemente e riduci l\'utilizzo dei dati" "Ottimizza la qualità dei contenuti multimediali" "Moderazione e Sicurezza" @@ -43,6 +44,11 @@ "Impossibile aggiornare il profilo" "Modifica profilo" "Aggiornamento del profilo…" + "Abilita le risposte alle discussioni" + "L\'app si riavvierà per applicare questa modifica." + "Prova le nostre ultime idee in fase di sviluppo. Queste funzionalità non sono definitive; potrebbero essere instabili e soggette a modifiche." + "Hai voglia di sperimentare?" + "Labs" "Impostazioni aggiuntive" "Chiamate audio e video" "Mancata corrispondenza di configurazione" diff --git a/features/preferences/impl/src/main/res/values-pt-rBR/translations.xml b/features/preferences/impl/src/main/res/values-pt-rBR/translations.xml index 5b3e75e7ec..f6e1bc90ba 100644 --- a/features/preferences/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/preferences/impl/src/main/res/values-pt-rBR/translations.xml @@ -10,9 +10,17 @@ "URL inválida, por favor verifique se o protocolo (http/https) está incluso e o endereço correto." "Ocultar avatares em solicitações de convite para salas" "Ocultar pré-visualizações de mídia na linha do tempo" + "Experimentos" "Envie fotos e vídeos com mais rapidez e reduza o uso de dados" "Otimizar a qualidade da mídia" "Moderação e segurança" + "Otimizar automaticamente as imagens para envios mais rápidos e arquivos com tamanhos menores." + "Otimizar qualidade de envio de imagens" + "%1$s. Toque aqui para alterar." + "Alta (1080p)" + "Baixa (480p)" + "Normal (720p)" + "Qualidade de envio de vídeos" "Provedor de notificações push" "Desative o editor de rich text para digitar Markdown manualmente." "Confirmações de leitura" @@ -36,6 +44,11 @@ "Não foi possível atualizar o perfil" "Editar perfil" "Atualizando o perfil…" + "Ativar respostas de tópicos" + "O app será reiniciado para aplicar esta mudança." + "Teste as nossas mais novas ideias em desenvolvimento. Esses recursos não estão finalizados; podem estar instáveis, e podem mudar." + "Se sentindo experimental?" + "Experimentos" "Configurações adicionais" "Chamadas de áudio e vídeo" "Não correspondência de configuração" diff --git a/features/preferences/impl/src/main/res/values-uz/translations.xml b/features/preferences/impl/src/main/res/values-uz/translations.xml index b01bd11fbd..82e9b24e98 100644 --- a/features/preferences/impl/src/main/res/values-uz/translations.xml +++ b/features/preferences/impl/src/main/res/values-uz/translations.xml @@ -8,14 +8,29 @@ "Maxsus element qo‘ng‘iroqlar bazasi URL manzili" "Element qo\'ng\'irog\'iga maxsus asosiy url or\'natish" "URL noto‘g‘ri, iltimos, protokol (http/https) va to‘g‘ri manzilni kiritganingizga ishonch hosil qiling." + "Xonaga taklif so‘rovlarida avatarlarni berkitish" + "Vaqt jadvalida mediaga razm solishlarni berkitish" "Rasm va videolarni tezroq yuklang va trafik sarfini kamaytiring" "Media sifatini yaxshilash" + "Moderatsiya va xavfsizlik" + "Tezroq yuklash va kichikroq fayl hajmi uchun rasmlarni avtomatik optimallashtirish." + "Rasm yuklash sifatini optimallashtirish" + "%1$s. Oʻzgartirish uchun bu yerga bosing." + "Yuqori (1080p)" + "Past (480p)" + "Standart (720p)" + "Video yuklash sifati" "Push bildirishnoma provayderi" "Boy matn muharriri o\'chiring Markdown bilan qo\'lda yozish uchun" "Kvitansiyalarni oʻqish" "Agar oʻchirib qo‘yilsa, sizning oʻqilganlik bildirishnomangiz hech kimga yuborilmaydi. Siz boshqa foydalanuvchilardan oʻqilganlik bildirishnomalarini olishda davom etasiz." "Mavjudligini ulashish" "Agar oʻchirib qoʻyilsa, siz oʻqilganlik haqidagi bildirishnomalarni yoki yozayotganingiz haqidagi xabarlarni yubora olmaysiz va qabul qila olmaysiz." + "Doim berkitilsin" + "Har doim ko‘rsatish" + "Shaxsiy xonalarda" + "Yashirin media har doim unga bosish orqali ko‘rsatilishi mumkin" + "Vaqt jadvalida media ko‘rsatish" "Xabar manbasini vaqt jadvalida ko‘rish imkoniyatini yoqing." "Sizda bloklangan foydalanuvchi yo‘q" "Blokdan chiqarish" @@ -55,6 +70,7 @@ Davom ettirsangiz, baʼzi sozlamalaringiz oʻzgarishi mumkin." "tizim sozlamalari" "Tizim bildirishnomalari o\'chirilgan" "Bildirishnomalar" + "Bildirishnoma tarixi" "Muammolarni bartaraf etish" "Bildirishnomalar bilan bog‘liq muammolarni bartaraf etish" diff --git a/features/preferences/impl/src/main/res/values-zh/translations.xml b/features/preferences/impl/src/main/res/values-zh/translations.xml index 7ac8952090..0c576b58b6 100644 --- a/features/preferences/impl/src/main/res/values-zh/translations.xml +++ b/features/preferences/impl/src/main/res/values-zh/translations.xml @@ -44,6 +44,10 @@ "无法更新个人资料" "编辑个人资料" "更新个人资料……" + "启用主题回复" + "应用将重启以应用此更改。" + "尝试我们最新的开发理念。这些功能尚未最终确定,可能不稳定,也可能会发生变化。" + "想尝试新功能?" "实验室" "更多设置" "音视频通话" diff --git a/features/rageshake/impl/src/main/res/values-it/translations.xml b/features/rageshake/impl/src/main/res/values-it/translations.xml index 8709881709..31fb95f9f6 100644 --- a/features/rageshake/impl/src/main/res/values-it/translations.xml +++ b/features/rageshake/impl/src/main/res/values-it/translations.xml @@ -14,5 +14,7 @@ "Invia istantanea schermo" "Per verificare che le cose funzionino come previsto, i log verranno inviati con il tuo messaggio. Per inviare solo il tuo messaggio, disattiva questa impostazione." "%1$s si è chiuso inaspettatamente l\'ultima volta che è stato usato. Vuoi condividere con noi un rapporto sull\'arresto anomalo?" + "Se riscontri problemi con le notifiche, caricare le regole per le notifiche push può aiutarci a individuare la causa principale. Tieni presente che queste regole possono contenere informazioni private, come il tuo nome visualizzato o le parole chiave per cui ricevere notifiche." + "Invia impostazioni di notifica" "Visualizza i log" diff --git a/features/rageshake/impl/src/main/res/values-pt-rBR/translations.xml b/features/rageshake/impl/src/main/res/values-pt-rBR/translations.xml index 046c1b30d7..7495d5946e 100644 --- a/features/rageshake/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/rageshake/impl/src/main/res/values-pt-rBR/translations.xml @@ -14,5 +14,7 @@ "Enviar captura de tela" "Os registros serão incluídos com sua mensagem para garantir que tudo esteja funcionando corretamente. Para enviar sua mensagem sem registros, desative essa configuração." "%1$s falhou inesperadamente na última vez que foi usado. Gostaria de compartilhar um relatório de falhas conosco?" + "Se estiver enfrentando problemas com as notificações, enviar as regras de notificações push pode ajudar-nos a descobrir o que está errado. Observe que as regras podem conter informações privadas, como o seu nome de exibição ou palavras chaves de notificação." + "Enviar configurações de notificação" "Ver registros" diff --git a/features/rageshake/impl/src/main/res/values-uz/translations.xml b/features/rageshake/impl/src/main/res/values-uz/translations.xml index fbeb0d3271..e3aceaa7d6 100644 --- a/features/rageshake/impl/src/main/res/values-uz/translations.xml +++ b/features/rageshake/impl/src/main/res/values-uz/translations.xml @@ -10,6 +10,7 @@ "Tavsif juda qisqa, nima boʻlganligi haqida batafsilroq maʼlumot bering. Rahmat!" "Buzilish jurnallarini yuboring" "Jurnallarga ruxsat bering" + "Sizning jurnallaringiz juda katta, shuning uchun bu hisobotga kiritilmaydi, iltimos ularni bizga boshqa usulda yuboring." "Ekran tasvirini yuboring" "Har bir narsa to\'ri ishlayotganiga ishonch hosil qilish uchun xabaringizga jurnallar kiritiladi. Xabarni jurnallarsiz yuborish uchun ushbu sozlamani oʻchiring." "%1$soxirgi marta ishlatilganda qulab tushdi. Biz bilan nosozlik hisobotini baham ko\'rmoqchimisiz?" diff --git a/features/reportroom/impl/src/main/res/values-uz/translations.xml b/features/reportroom/impl/src/main/res/values-uz/translations.xml index b10ea22735..e7424ade8f 100644 --- a/features/reportroom/impl/src/main/res/values-uz/translations.xml +++ b/features/reportroom/impl/src/main/res/values-uz/translations.xml @@ -1,4 +1,8 @@ + "Hisobotingiz muvaffaqiyatli yuborildi, ammo xonadan chiqishda muammo yuzaga keldi. Iltimos, qaytadan urinib ko‘ring." + "Xonani tark etish imkonsiz" + "Bu xona haqida administratoringizga xabar bering. Agar xabarlar shifrlangan bo‘lsa, administratoringiz ularni o‘qiy olmaydi." + "Xabar berish sababini tushuntiring…" "Xona ustidan shikoyat qilish" diff --git a/features/rolesandpermissions/impl/src/main/res/values-cs/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-cs/translations.xml index 67e65142d8..3df8e0afbb 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-cs/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-cs/translations.xml @@ -1,14 +1,16 @@ - "Pouze správci" + "Správce" "Vykázat lidi" "Odstranit zprávy" - "Pozvěte lidi a přijímejte žádosti o připojení" + "Člen" + "Pozvat přátele" + "Spravovat členy" "Zprávy a obsah" - "Správci a moderátoři" - "Odeberte lidi a odmítněte žádosti o připojení" + "Moderátor" + "Odebrat osoby" "Změnit avatar místnosti" - "Upravit místnost" + "Upravit podrobnosti" "Změnit název místnosti" "Změnit téma místnosti" "Odeslat zprávy" @@ -32,6 +34,13 @@ "Máte neuložené změny." "Uložit změny?" "V této místnosti nejsou žádní vykázaní uživatelé." + + "%1$d vykázán(a)" + "%1$d vykázáni" + "%1$d vykázáných" + + "Zkontrolujte pravopis nebo zkuste nové vyhledávání" + "Žádné výsledky pro “%1$s”" "%1$d osoba" "%1$d osoby" @@ -44,8 +53,14 @@ "Zrušit vykázání z místnosti" "Vykázaní" "Členové" - "Pouze správci" - "Správci a moderátoři" + + "%1$d pozván(a)" + "%1$d pozváni" + "%1$d pozvaných" + + "Čekající" + "Správce" + "Moderátor" "Vlastník" "Členové místnosti" "Rušení vykázání %1$s" @@ -58,10 +73,12 @@ "Zprávy a obsah" "Moderátoři" "Vlastníci" + "Oprávnění" "Obnovit oprávnění" "Po obnovení oprávnění ztratíte aktuální nastavení." "Obnovit oprávnění?" "Role" "Podrobnosti místnosti" - "Role a oprávnění" + "Detaily prostoru" + "Role a oprávnění" diff --git a/features/rolesandpermissions/impl/src/main/res/values-fa/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-fa/translations.xml index 996b50bf62..c526d059bc 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-fa/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-fa/translations.xml @@ -33,6 +33,10 @@ "تغییراتی ذخیره نشده دارید." "ذخیرهٔ تغییرات؟" "هیچ کاربر محرومی در این اتاق نیست." + + "%1$d نفر" + "%1$d نفر" + "برداشت و تحریم عضو" "تنها برداشتن عضو" "رفع انسداد" diff --git a/features/rolesandpermissions/impl/src/main/res/values-fi/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-fi/translations.xml index 658828ae41..1322089dc8 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-fi/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-fi/translations.xml @@ -1,14 +1,16 @@ - "Vain ylläpitäjät" + "Ylläpitäjä" "Porttikieltojen antaminen" "Viestien poistaminen" + "Jäsen" "Ihmisten kutsuminen ja liittymispyyntöjen hyväksyminen" + "Jäsenien hallinta" "Viestit ja sisältö" - "Ylläpitäjät ja valvojat" + "Valvoja" "Henkilöiden poistaminen ja liittymispyyntöjen hylkääminen" "Huoneen avatarin vaihtaminen" - "Muokkaa huonetta" + "Muokkaa tietoja" "Huoneen nimen vaihtaminen" "Huoneen aiheen vaihtaminen" "Viestien lähettäminen" @@ -31,7 +33,7 @@ "Jäsenet" "Sinulla on tallentamattomia muutoksia" "Tallennetaanko muutokset?" - "Tässä huoneessa ei ole porttikieltoja" + "Porttikiellettyjä käyttäjiä ei ole." "%1$d henkilö" "%1$d henkilöä" @@ -43,8 +45,8 @@ "Poista porttikielto huoneesta" "Porttikiellot" "Jäsenet" - "Vain ylläpitäjät" - "Ylläpitäjät ja valvojat" + "Ylläpitäjä" + "Valvoja" "Omistaja" "Huoneen jäsenet" "Poistetaan käyttäjän %1$s porttikieltoa" @@ -57,10 +59,12 @@ "Viestit ja sisältö" "Valvojat" "Omistajat" + "Oikeudet" "Nollaa oikeudet" "Kun nollaat käyttöoikeudet, menetät nykyiset asetukset." "Nollataanko oikeudet?" "Roolit" "Huoneen tiedot" + "Tilan tiedot" "Roolit ja oikeudet" diff --git a/features/rolesandpermissions/impl/src/main/res/values-fr/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-fr/translations.xml index 36add59a2d..f44072366d 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-fr/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-fr/translations.xml @@ -34,9 +34,15 @@ "Vous avez des modifications non-enregistrées." "Enregistrer les changements ?" "Il n’y a pas d’utilisateur banni." + + "%1$d Banni(e)" + "%1$d Banni(e)s" + + "Vérifiez la saisie ou effectuez une nouvelle recherche" + "Aucun résultat pour «%1$s»" - "%1$d personne" - "%1$d personnes" + "%1$d Personne" + "%1$d Personnes" "Bannir du salon" "Retirer le membre uniquement" @@ -45,6 +51,11 @@ "Débannir du salon" "Bannis" "Membres" + + "%1$d Invité(e)" + "%1$d Invité(e)s" + + "En attente" "Administrateurs" "Modérateurs" "Propriétaire" diff --git a/features/rolesandpermissions/impl/src/main/res/values-it/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-it/translations.xml index 6b11b7946b..2b439a6c61 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-it/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-it/translations.xml @@ -1,14 +1,16 @@ - "Solo amministratori" + "Amministratore" "Escludi membri" "Rimuovi messaggi" - "Invita persone e accetta richieste di partecipazione" + "Membro" + "Invita persone" + "Gestisci membri" "Messaggi e contenuti" - "Amministratori e moderatori" - "Rimuovi le persone e rifiuta le richieste di partecipazione" + "Moderatore" + "Rimuovi membri" "Cambia avatar della stanza" - "Modifica stanza" + "Modifica dettagli" "Cambia il nome della stanza" "Cambiare l\'argomento della stanza" "Inviare messaggi" @@ -31,10 +33,16 @@ "Membri" "Hai delle modifiche non salvate." "Salvare le modifiche?" - "Non ci sono utenti esclusi in questa stanza." + "Non ci sono utenti bannati." + + "%1$d Bannato" + "%1$d Bannati" + + "Controlla l\'ortografia o prova una nuova ricerca" + "Nessun risultato per “%1$s ”" - "%1$d persona" - "%1$d persone" + "%1$d Persona" + "%1$d Persone" "Rimuovi ed escludi" "Rimuovi soltanto" @@ -43,8 +51,13 @@ "Riammetti nella stanza" "Esclusi" "Membri" - "Solo amministratori" - "Amministratori e moderatori" + + "%1$d Invitato" + "%1$d Invitati" + + "In attesa" + "Amministratore" + "Moderatore" "Proprietario" "Membri della stanza" "Riammissione di %1$s" @@ -57,10 +70,12 @@ "Messaggi e contenuti" "Moderatori" "Proprietari" + "Autorizzazioni" "Reimpostare le autorizzazioni" "Una volta reimpostate le autorizzazioni, perderai le impostazioni correnti." "Reimpostare autorizzazioni?" "Ruoli" "Dettagli della stanza" + "Dettagli dello spazio" "Ruoli e autorizzazioni" diff --git a/features/rolesandpermissions/impl/src/main/res/values-pt-rBR/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-pt-rBR/translations.xml index ec2e5bc558..886d3c541d 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-pt-rBR/translations.xml @@ -1,14 +1,16 @@ - "Somente administradores" + "Administradores" "Banir pessoas" "Remover mensagens" - "Convide pessoas e aceite solicitações de entrada" + "Membro" + "Convidar pessoas" + "Gerenciar membros" "Mensagens e conteúdo" - "Administradores e moderadores" - "Remover pessoas e recusar solicitações de entrada" + "Moderador" + "Remover pessoas" "Alterar avatar da sala" - "Editar sala" + "Editar detalhes" "Alterar nome da sala" "Alterar tópico da sala" "Enviar mensagens" @@ -31,7 +33,13 @@ "Membros" "Você tem alterações não salvas." "Salvar alterações?" - "Não há usuários banidos nesta sala." + "Não há usuários banidos." + + "%1$d banido" + "%1$d banidos" + + "Confira a ortografia ou tente uma nova busca" + "Nenhum resultado para “%1$s”" "%1$d pessoa" "%1$d pessoas" @@ -43,8 +51,13 @@ "Desbanir da sala" "Banidos" "Membros" - "Somente administradores" - "Administradores e moderadores" + + "%1$d convidado" + "%1$d convidados" + + "Pendente" + "Administradores" + "Moderador" "Proprietário" "Membros da sala" "Desbanindo %1$s" @@ -57,10 +70,12 @@ "Mensagens e conteúdo" "Moderadores" "Proprietários" + "Permissões" "Redefinir permissões" "Depois de redefinir as permissões, você perderá as configurações atuais." "Redefinir permissões?" "Cargos" "Detalhes da sala" + "Detalhes do espaço" "Cargos e permissões" diff --git a/features/rolesandpermissions/impl/src/main/res/values-uz/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-uz/translations.xml index 61329b8577..f56210a29a 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-uz/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-uz/translations.xml @@ -15,13 +15,17 @@ "Administratorlarni tahrirlash" "Bu amalni bekor qila olmaysiz. Siz foydalanuvchini o‘zingiz bilan bir xil quvvat darajasiga ega bo‘lishga undayapsiz." "Admin qo‘shilsinmi?" + "Bu amalni bekor qila olmaysiz. Siz egalikni tanlangan foydalanuvchilarga o‘tkazmoqdasiz. Tark etsangiz, bu doimiy bo‘ladi." + "Egalik huquqini o‘tkazasizmi?" "Pastga tushirish" "Siz oʻzingizni imtiyozlardan mahrum qilayotganingiz sababli, bu o‘zgarishni bekor qila olmaysiz. Agar xonadagi so‘nggi imtiyozli foydalanuvchi bo‘lsangiz, imtiyozlarni qayta tiklash imkonsiz bo‘ladi." "O‘z darajangizni pasaytirmoqchimisiz?" "%1$s (Jarayonda)" "(Kutilmoqda)" "Administratorlar avtomatik ravishda moderator imtiyozlariga ega" + "Egalar avtomatik ravishda administrator huquqlariga ega." "Moderatorlarni tahrirlash" + "Egalarni tanlang" "Adminlar" "Moderatorlar" "Azolar" @@ -36,19 +40,23 @@ "Faqat aʻzoni olib tashlash" "Taqiqni bekor qilish" "Agar taklif qilinsa, ular bu xonaga qayta qo‘shilishlari mumkin." + "Xonadan taqiqni olib tashlash" "Taqiqlangan" "Azolar" "Faqat adminlar" "Adminlar va moderatorlar" + "Egasi" "Xona a\'zolari" "Taqiqni bekor qilish %1$s" "Adminlar" + "Adminlar va egalari" "Rolimni o‘zgartirish" "Aʼzolikka tushirish" "Moderatorga pasaytirish" "Aʻzo moderatsiyasi" "Xabarlar va kontent" "Moderatorlar" + "Egalari" "Ruxsatlarni tiklash" "Ruxsatlarni asliga qaytargach, joriy sozlamalarni yoʻqotasiz." "Ruxsatlar asliga qaytarilsinmi?" diff --git a/features/rolesandpermissions/impl/src/main/res/values-zh/translations.xml b/features/rolesandpermissions/impl/src/main/res/values-zh/translations.xml index 3a11398599..d2882d8ab4 100644 --- a/features/rolesandpermissions/impl/src/main/res/values-zh/translations.xml +++ b/features/rolesandpermissions/impl/src/main/res/values-zh/translations.xml @@ -31,7 +31,7 @@ "成员" "您有未保存的更改。" "保存更改?" - "此聊天室里没有被封禁的用户。" + "没有被封禁的用户。" "%1$d 人" @@ -61,5 +61,6 @@ "重置权限?" "角色" "聊天室详情" + "空间详情" "角色与权限" diff --git a/features/roomaliasresolver/impl/src/main/res/values-uz/translations.xml b/features/roomaliasresolver/impl/src/main/res/values-uz/translations.xml index 0499fed4f5..d79cdadcc2 100644 --- a/features/roomaliasresolver/impl/src/main/res/values-uz/translations.xml +++ b/features/roomaliasresolver/impl/src/main/res/values-uz/translations.xml @@ -1,4 +1,5 @@ + "Biz bu xonani oldindan ko‘rishni ko‘rsata olmadik " "Xona taxalluslari yechilmadi." diff --git a/features/roomdetails/impl/src/main/res/values-bg/translations.xml b/features/roomdetails/impl/src/main/res/values-bg/translations.xml index e23ba71ff0..4ea6d24af6 100644 --- a/features/roomdetails/impl/src/main/res/values-bg/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-bg/translations.xml @@ -90,8 +90,8 @@ "Хората могат да се присъединят само ако са поканени" "Само с покана" "Достъп до стаята" - "Пространствата в момента не се поддържат" "Членове на пространството" + "Пространствата в момента не се поддържат" "Видима в директорията на обществените стаи" "Всеки" "Кой може да чете историята" diff --git a/features/roomdetails/impl/src/main/res/values-cs/translations.xml b/features/roomdetails/impl/src/main/res/values-cs/translations.xml index 6e1214eea0..fc19bf400e 100644 --- a/features/roomdetails/impl/src/main/res/values-cs/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-cs/translations.xml @@ -1,19 +1,21 @@ - "Aby byla místnost v adresáři viditelná, je třeba zadat její adresu." - "Adresa místnosti" + "Budete potřebovat adresu místnosti, aby byla viditelná v adresáři místností." + "Upravit adresu" "Při aktualizaci nastavení oznámení došlo k chybě." "Váš domovský server tuto možnost v zašifrovaných místnostech nepodporuje, v některých místnostech nemusíte být upozorněni." "Hlasování" - "Pouze správci" + "Správce" "Vykázat lidi" "Odstranit zprávy" - "Pozvěte lidi a přijímejte žádosti o připojení" + "Člen" + "Pozvat přátele" + "Spravovat členy" "Zprávy a obsah" - "Správci a moderátoři" - "Odeberte lidi a odmítněte žádosti o připojení" + "Moderátor" + "Odebrat osoby" "Změnit avatar místnosti" - "Upravit místnost" + "Upravit podrobnosti" "Změnit název místnosti" "Změnit téma místnosti" "Odeslat zprávy" @@ -40,7 +42,7 @@ "Šifrováno" "Není šifrováno" "Veřejná místnost" - "Upravit místnost" + "Upravit podrobnosti" "Došlo k neznámé chybě a informace nebylo možné změnit." "Nelze aktualizovat místnost" "Zprávy jsou zabezpečeny zámky. Pouze vy a příjemci máte jedinečné klíče k jejich odemčení." @@ -60,7 +62,7 @@ "Připnuté zprávy" "Profil" "Žádosti o vstup" - "Role a oprávnění" + "Role a oprávnění" "Název místnosti" "Zabezpečení a soukromí" "Zabezpečení" @@ -69,6 +71,13 @@ "Téma" "Aktualizace místnosti…" "V této místnosti nejsou žádní vykázaní uživatelé." + + "%1$d vykázán(a)" + "%1$d vykázáni" + "%1$d vykázáných" + + "Zkontrolujte pravopis nebo zkuste nové vyhledávání" + "Žádné výsledky pro “%1$s”" "%1$d osoba" "%1$d osoby" @@ -81,8 +90,14 @@ "Zrušit vykázání z místnosti" "Vykázaní" "Členové" - "Pouze správci" - "Správci a moderátoři" + + "%1$d pozván(a)" + "%1$d pozváni" + "%1$d pozvaných" + + "Čekající" + "Správce" + "Moderátor" "Vlastník" "Členové místnosti" "Rušení vykázání %1$s" @@ -109,14 +124,15 @@ "Zprávy a obsah" "Moderátoři" "Vlastníci" + "Oprávnění" "Obnovit oprávnění" "Po obnovení oprávnění ztratíte aktuální nastavení." "Obnovit oprávnění?" "Role" "Podrobnosti místnosti" - "Role a oprávnění" - "Přidat adresu místnosti" - "Kdokoli může požádat o vstup do místnosti, ale správce nebo moderátor bude muset žádost přijmout." + "Role a oprávnění" + "Přidat adresu" + "Všichni musí požádat o přístup." "Požádat o připojení" "Ano, povolit šifrování" "Po aktivaci nelze šifrování místnosti deaktivovat. Historie zpráv bude viditelná pouze pro členy místnosti od doby, kdy byli pozváni nebo od té doby, co do místnosti vstoupili. @@ -126,17 +142,21 @@ Nedoporučujeme povolovat šifrování pro místnosti, které může kdokoli naj "Jakmile je povoleno, šifrování nelze zakázat." "Šifrování" "Povolit koncové šifrování" - "Každý může najít a vstoupit" + "Vstoupit může kdokoli." "Kdokoliv" - "Lidé mohou vstoupit, pouze pokud jsou pozváni" + "Vyberte, kteří členové prostorů se k této místnosti mohou připojit bez pozvánky. %1$s" + "Vstoupit mohou pouze pozvaní lidé." "Pouze pro zvané" - "Přístup do místnosti" - "Prostory nejsou aktuálně podporovány" + "Přístup" + "Vstoupit může kdokoli z autorizovaných prostorů." + "Vstoupit může kdokoli v %1$s." "Členové prostoru" - "Aby byla místnost v adresáři viditelná, je třeba zadat její adresu." - "Adresa místnosti" + "Prostory nejsou aktuálně podporovány" + "Budete potřebovat adresu místnosti, aby byla viditelná v adresáři místností." + "Adresa" "Umožněte nalezení této místnosti prohledáním adresáře veřejných místností na %1$s" - "Viditelné v adresáři veřejných místností" + "Umožnit nalezení vyhledáváním ve veřejném adresáři." + "Viditelné ve veřejném adresáři" "Kdokoliv" "Kdo může číst historii" "Pouze členové od té doby, co byli pozváni" @@ -144,6 +164,7 @@ Nedoporučujeme povolovat šifrování pro místnosti, které může kdokoli naj "Adresy místností představují způsoby, jak najít místnosti a získat k nim přístup. Díky tomu můžete svoji místnost snadno sdílet s ostatními. Můžete se rozhodnout publikovat svou místnost ve veřejném adresáři místnosti vašeho domovského serveru." "Publikování místnosti" - "Viditelnost místnosti" + "Adresy slouží k vyhledávání a přístupu do místností a prostorů. Díky tomu je také můžete snadno sdílet s ostatními." + "Viditelnost" "Zabezpečení a soukromí" diff --git a/features/roomdetails/impl/src/main/res/values-cy/translations.xml b/features/roomdetails/impl/src/main/res/values-cy/translations.xml index 0a3c05285a..97d39509fa 100644 --- a/features/roomdetails/impl/src/main/res/values-cy/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-cy/translations.xml @@ -136,8 +136,8 @@ Nid ydym yn argymell galluogi amgryptio ar gyfer ystafelloedd y gall unrhyw un d "Dim ond os cawn nhw wahoddiad gall pobl ymuno" "Gwahoddiad yn unig" "Mynediad ystafell" - "Nid yw gofodau\'n cael eu cefnogi ar hyn o bryd" "Aelodau gofod" + "Nid yw gofodau\'n cael eu cefnogi ar hyn o bryd" "Bydd angen cyfeiriad ystafell arnoch i\'w wneud yn weladwy yn y cyfeiriadur." "Cyfeiriad yr ystafell" "Caniatáu i\'r ystafell hon gael ei chanfod trwy chwilio cyfeiriadur ystafelloedd cyhoeddus %1$s" diff --git a/features/roomdetails/impl/src/main/res/values-da/translations.xml b/features/roomdetails/impl/src/main/res/values-da/translations.xml index 63a20e51ec..c2ed3caaca 100644 --- a/features/roomdetails/impl/src/main/res/values-da/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-da/translations.xml @@ -130,8 +130,8 @@ Vi anbefaler ikke at aktivere kryptering for rum, som alle kan finde og deltage "Andre kan kun deltage, hvis de bliver inviteret" "Kun med invitation" "Adgang til rummet" - "Grupper understøttes ikke i øjeblikket" "Medlemmer af gruppen" + "Grupper understøttes ikke i øjeblikket" "Du skal bruge en rum-adresse for at gøre den synlig i kataloget." "Tillad, at dette rum kan findes ved at søge i %1$s fortegnelse over offentlige rum" "Synlig i det offentlige register over rum" diff --git a/features/roomdetails/impl/src/main/res/values-de/translations.xml b/features/roomdetails/impl/src/main/res/values-de/translations.xml index ec71ebc015..89ef69c173 100644 --- a/features/roomdetails/impl/src/main/res/values-de/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-de/translations.xml @@ -130,8 +130,8 @@ Wir empfehlen keine Verschlüsselung für Chats zu aktivieren, die jeder finden "Personen können nur beitreten, wenn sie eingeladen werden." "Nur auf Einladung" "Chat Zugang" - "Spaces werden zur Zeit nicht unterstützt." "Spacemitglieder" + "Spaces werden zur Zeit nicht unterstützt." "Du benötigst eine Chat-Adresse, um den Chat im Verzeichnis sichtbar zu machen." "Chatroomadresse" "Erlaube das Auffinden dieses Chats durch Suche im öffentlichen Verzeichnis von %1$s" diff --git a/features/roomdetails/impl/src/main/res/values-el/translations.xml b/features/roomdetails/impl/src/main/res/values-el/translations.xml index 0eadb5f775..a2deb1c706 100644 --- a/features/roomdetails/impl/src/main/res/values-el/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-el/translations.xml @@ -121,8 +121,8 @@ "Τα άτομα μπορούν να συμμετάσχουν μόνο εάν έχουν προσκληθεί" "Μόνο πρόσκληση" "Πρόσβαση στην αίθουσα" - "Οι χώροι δεν υποστηρίζονται προς το παρόν" "Μέλη χώρου" + "Οι χώροι δεν υποστηρίζονται προς το παρόν" "Θα χρειαστείτε μια διεύθυνση αίθουσας για να την κάνετε ορατή στον κατάλογο." "Επιστρέψτε την εύρεση αυτής της αίθουσας με αναζήτηση στον κατάλογο %1$s δημοσίων αιθουσών" "Ορατή στον κατάλογο δημόσιων αιθουσών" diff --git a/features/roomdetails/impl/src/main/res/values-es/translations.xml b/features/roomdetails/impl/src/main/res/values-es/translations.xml index d58ddcd598..c179a4d16e 100644 --- a/features/roomdetails/impl/src/main/res/values-es/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-es/translations.xml @@ -121,8 +121,8 @@ No recomendamos habilitar el cifrado para las salas que cualquiera pueda encontr "Las personas solo pueden unirse si están invitadas" "Solo por invitación" "Acceso a la sala" - "No se admiten los espacios por el momento." "Miembros del espacio" + "No se admiten los espacios por el momento." "Necesitarás una dirección de sala para que sea visible en el directorio." "Permite encontrar esta sala buscando en el directorio de salas públicas de %1$s" "Visible en el directorio de salas públicas" diff --git a/features/roomdetails/impl/src/main/res/values-et/translations.xml b/features/roomdetails/impl/src/main/res/values-et/translations.xml index 331bce4ba5..7a315de168 100644 --- a/features/roomdetails/impl/src/main/res/values-et/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-et/translations.xml @@ -136,8 +136,8 @@ Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega "Liituda saab vaid kutse olemasolul" "Vaid kutsega" "Ligipääs" - "Kogukondade tugi veel puudub" "Kogukonna liikmed" + "Kogukondade tugi veel puudub" "Selleks, et jututuba oleks nähtav jututubade avalikus kataloogis, vajab ta aadressi." "Aadress" "Võimalda leida seda jututuba avalikust kataloogist otsides „%1$s“" diff --git a/features/roomdetails/impl/src/main/res/values-eu/translations.xml b/features/roomdetails/impl/src/main/res/values-eu/translations.xml index 89a77bd4c8..5d0f61fb40 100644 --- a/features/roomdetails/impl/src/main/res/values-eu/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-eu/translations.xml @@ -108,8 +108,8 @@ "Gonbidatutako pertsonak bakarrik sartu ahal izango dira" "Gonbidapen bidez" "Gelarako sarbidea" - "Gaur-gaurkoz ez da guneekin bateragarria" "Guneko kideak" + "Gaur-gaurkoz ez da guneekin bateragarria" "Gelaren helbidea" "Gela publikoen direktorioan ikusgai" "Edonork" diff --git a/features/roomdetails/impl/src/main/res/values-fa/translations.xml b/features/roomdetails/impl/src/main/res/values-fa/translations.xml index 3243eff70f..c04650417c 100644 --- a/features/roomdetails/impl/src/main/res/values-fa/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-fa/translations.xml @@ -69,6 +69,10 @@ "موضوع" "به‌روز کردن اتاق…" "هیچ کاربر محرومی در این اتاق نیست." + + "%1$d نفر" + "%1$d نفر" + "برداشت و تحریم عضو" "تنها برداشتن عضو" "رفع انسداد" @@ -120,8 +124,8 @@ "افراد فقط در صورت دعوت می‌توانند بپیوندند" "فقط دعوتی" "دسترسی اتاق" - "در حال حاضر فضاها پشتیبانی نمی‌شوند" "اعضای فضا" + "در حال حاضر فضاها پشتیبانی نمی‌شوند" "نشانی اتاق" "هرکسی" "انتشار اتاق" diff --git a/features/roomdetails/impl/src/main/res/values-fi/translations.xml b/features/roomdetails/impl/src/main/res/values-fi/translations.xml index f1cf00453a..b696660b62 100644 --- a/features/roomdetails/impl/src/main/res/values-fi/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-fi/translations.xml @@ -1,19 +1,21 @@ - "Tarvitset huoneen osoitteen, jotta se näkyy hakemistossa." - "Huoneen osoite" + "Tarvitset osoitteen, jotta se näkyy julkisessa hakemistossa." + "Muokkaa osoitetta" "Ilmoitusasetusten muokkaamisessa tapahtui virhe." "Kotipalvelimesi ei tue tätä vaihtoehtoa salatuissa huoneissa, joten et ehkä saa ilmoitusta joissakin huoneissa." "Kyselyt" - "Vain ylläpitäjät" + "Ylläpitäjä" "Porttikieltojen antaminen" "Viestien poistaminen" + "Jäsen" "Ihmisten kutsuminen ja liittymispyyntöjen hyväksyminen" + "Jäsenien hallinta" "Viestit ja sisältö" - "Ylläpitäjät ja valvojat" + "Valvoja" "Henkilöiden poistaminen ja liittymispyyntöjen hylkääminen" "Huoneen avatarin vaihtaminen" - "Muokkaa huonetta" + "Muokkaa tietoja" "Huoneen nimen vaihtaminen" "Huoneen aiheen vaihtaminen" "Viestien lähettäminen" @@ -40,7 +42,7 @@ "Salattu" "Ei salattu" "Julkinen huone" - "Muokkaa huonetta" + "Muokkaa tietoja" "Tuntematon virhe tapahtui, eikä tietoja voitu muuttaa." "Huoneen muokkaaminen ei onnistunut" "Viestisi suojataan lukoilla. Vain sinulla ja viesiten vastaanottajilla on uniikit avaimet niiden avaamiseen." @@ -50,7 +52,7 @@ "Tämän huoneen mykistyksen poistaminen epäonnistui, yritä uudelleen." "Älä sulje sovellusta ennen kuin se on valmis." "Valmistellaan kutsuja…" - "Kutsu ihmisiä" + "Kutsu henkilöitä" "Poistu keskustelusta" "Poistu huoneesta" "Media ja tiedostot" @@ -68,7 +70,7 @@ "Huoneen tiedot" "Aihe" "Muokataan huonetta…" - "Tässä huoneessa ei ole porttikieltoja" + "Porttikiellettyjä käyttäjiä ei ole." "%1$d henkilö" "%1$d henkilöä" @@ -80,8 +82,8 @@ "Poista porttikielto huoneesta" "Porttikiellot" "Jäsenet" - "Vain ylläpitäjät" - "Ylläpitäjät ja valvojat" + "Ylläpitäjä" + "Valvoja" "Omistaja" "Huoneen jäsenet" "Poistetaan käyttäjän %1$s porttikieltoa" @@ -108,14 +110,15 @@ "Viestit ja sisältö" "Valvojat" "Omistajat" + "Oikeudet" "Nollaa oikeudet" "Kun nollaat käyttöoikeudet, menetät nykyiset asetukset." "Nollataanko oikeudet?" "Roolit" "Huoneen tiedot" "Roolit ja oikeudet" - "Lisää huoneen osoite" - "Kuka tahansa voi pyytää saada liittyä huoneeseen, mutta ylläpitäjän tai valvojan on hyväksyttävä pyyntö." + "Lisää osoite" + "Kaikkien on pyydettävä pääsyä." "Pyydä liittymistä" "Kyllä, ota salaus käyttöön" "Kun salaus on kerran otettu käyttöön, sitä ei voi poistaa käytöstä. Viestihistoria näkyy vain huoneen jäsenille kutsusta tai liittymisestä lähtien. @@ -125,17 +128,18 @@ Emme suosittele salauksen ottamista käyttöön huoneissa, jotka kuka tahansa vo "Kun salaus on kerran otettu käyttöön, sitä ei voi poistaa käytöstä." "Salaus" "Ota päästä päähän -salaus käyttöön" - "Kuka tahansa voi löytää ja liittyä." + "Kuka tahansa voi liittyä." "Kuka tahansa" - "Vain kutsutut henkilöt voivat liittyä" + "Vain kutsutut henkilöt voivat liittyä." "Vain kutsutut" - "Huoneeseen pääsy" - "Tiloja ei tällä hetkellä tueta" + "Pääsy" "Tilan jäsenet" - "Tarvitset huoneen osoitteen, jotta se näkyy hakemistossa." - "Huoneen osoite" + "Tiloja ei tällä hetkellä tueta" + "Tarvitset osoitteen, jotta se näkyy julkisessa hakemistossa." + "Osoite" "Salli tämän huoneen löytäminen hakemalla %1$s -palvelimen julkisesta huonehakemistosta." - "Näkyy julkisessa huonehakemistossa" + "Anna muiden löytää tämä julkisen hakemiston kautta." + "Näkyy julkisessa hakemistossa" "Kuka tahansa" "Kuka voi lukea viestihistoriaa" "Jäsenet vasta kutsusta lähtien" @@ -143,6 +147,6 @@ Emme suosittele salauksen ottamista käyttöön huoneissa, jotka kuka tahansa vo "Huoneosoitteet ovat tapoja löytää ja käyttää huoneita. Näin voit myös helposti jakaa huoneesi muiden kanssa. Voit halutessasi julkaista huoneesi kotipalvelimesi julkisessa huonehakemistossa." "Huoneen julkaiseminen" - "Huoneen näkyvyys" + "Näkyvyys" "Turvallisuus ja yksityisyys" diff --git a/features/roomdetails/impl/src/main/res/values-fr/translations.xml b/features/roomdetails/impl/src/main/res/values-fr/translations.xml index 4868d1413b..79af58f0e3 100644 --- a/features/roomdetails/impl/src/main/res/values-fr/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-fr/translations.xml @@ -71,9 +71,15 @@ "Sujet" "Mise à jour du salon…" "Il n’y a pas d’utilisateur banni." + + "%1$d Banni(e)" + "%1$d Banni(e)s" + + "Vérifiez la saisie ou effectuez une nouvelle recherche" + "Aucun résultat pour «%1$s»" - "%1$d personne" - "%1$d personnes" + "%1$d Personne" + "%1$d Personnes" "Bannir du salon" "Retirer le membre uniquement" @@ -82,6 +88,11 @@ "Débannir du salon" "Bannis" "Membres" + + "%1$d Invité(e)" + "%1$d Invité(e)s" + + "En attente" "Administrateurs" "Modérateurs" "Propriétaire" @@ -133,8 +144,8 @@ Nous ne recommandons pas d’activer le chiffrement pour les salons que tout le "Seules les personnes invitées peuvent rejoindre." "Sur invitation uniquement" "Accès" - "Les Espaces ne sont pas encore supportés" "Membres de l’espace" + "Les Espaces ne sont pas encore supportés" "Vous aurez besoin d’une adresse pour le rendre visible dans l’annuaire public." "Adresse" "Autoriser le salon à apparaître dans les résultats de recherche dans le répertoire %1$s des salons publics" @@ -147,6 +158,7 @@ Nous ne recommandons pas d’activer le chiffrement pour les salons que tout le "Les adresses de salon sont un moyen de trouver et d’accéder aux salons. Cela vous permet également de partager facilement votre salon avec d’autres personnes. Vous pouvez choisir de publier votre salon dans l’annuaire des salons publics de votre serveur d’accueil." "Publication du salon" + "Les adresses permettent de trouver et d’accéder aux salons et aux espaces. Elles facilitent également leur partage avec d’autres personnes." "Visibilité" "Sécurité & confidentialité" diff --git a/features/roomdetails/impl/src/main/res/values-hu/translations.xml b/features/roomdetails/impl/src/main/res/values-hu/translations.xml index f105fc6262..bbcf93fcf7 100644 --- a/features/roomdetails/impl/src/main/res/values-hu/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-hu/translations.xml @@ -134,8 +134,8 @@ Nem javasoljuk a titkosítás engedélyezését az olyan szobákban, amelyeket b "Csak a meghívott emberek léphetnek be." "Csak meghívásos" "Hozzáférés" - "A terek jelenleg nem támogatottak" "A tér tagjai" + "A terek jelenleg nem támogatottak" "Szüksége lesz egy szobacímre, hogy láthatóvá tegye a szobakatalógusban." "Cím" "A szoba megtalálhatóvá tétele a(z) %1$s nyilvános szobakatalógusában való kereséssel." diff --git a/features/roomdetails/impl/src/main/res/values-in/translations.xml b/features/roomdetails/impl/src/main/res/values-in/translations.xml index 431c4e66f1..097cd371f6 100644 --- a/features/roomdetails/impl/src/main/res/values-in/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-in/translations.xml @@ -120,8 +120,8 @@ Kami tidak menyarankan untuk mengaktifkan enkripsi untuk ruangan yang dapat dite "Orang hanya dapat bergabung jika mereka diundang" "Hanya undangan" "Akses ruangan" - "Space saat ini tidak didukung" "Anggota space" + "Space saat ini tidak didukung" "Anda akan memerlukan alamat ruangan untuk membuatnya terlihat dalam direktori." "Izinkan ruangan ini ditemukan dengan mencari direktori ruangan %1$s publik" "Terlihat di direktori ruangan publik" diff --git a/features/roomdetails/impl/src/main/res/values-it/translations.xml b/features/roomdetails/impl/src/main/res/values-it/translations.xml index 1a315d8de0..3d83dba3cb 100644 --- a/features/roomdetails/impl/src/main/res/values-it/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-it/translations.xml @@ -1,19 +1,21 @@ - "Avrai bisogno di un indirizzo della stanza per renderla visibile nell\'elenco." - "Indirizzo della stanza" + "Per renderlo visibile nell\'elenco pubblico, avrai bisogno di un indirizzo." + "Modifica indirizzo" "Si è verificato un errore durante l\'aggiornamento delle impostazioni di notifica." "Il tuo homeserver non supporta questa opzione nelle stanze crifrate, quindi potresti non ricevere notifiche in alcune stanze." "Sondaggi" - "Solo amministratori" + "Amministratore" "Escludi membri" "Rimuovi messaggi" - "Invita persone e accetta richieste di partecipazione" + "Membro" + "Invita persone" + "Gestisci membri" "Messaggi e contenuti" - "Amministratori e moderatori" - "Rimuovi le persone e rifiuta le richieste di partecipazione" + "Moderatore" + "Rimuovi membri" "Cambia avatar della stanza" - "Modifica stanza" + "Modifica dettagli" "Cambia il nome della stanza" "Cambiare l\'argomento della stanza" "Inviare messaggi" @@ -40,7 +42,7 @@ "Cifrata" "Non cifrata" "Stanza pubblica" - "Modifica stanza" + "Modifica dettagli" "Si è verificato un errore sconosciuto e non è stato possibile modificare le informazioni." "Impossibile aggiornare la stanza" "I messaggi sono protetti da lucchetti. Solo tu e i destinatari avete le chiavi univoche per sbloccarli." @@ -48,6 +50,8 @@ "Si è verificato un errore durante il caricamento delle impostazioni di notifica." "Impostazione del silenzioso fallita per questa stanza, riprova." "Disattivazione del silenzioso di questa stanza fallita, riprova." + "Non chiudere l\'app fino al completamento." + "Preparazione degli inviti…" "Invita persone" "Abbandona la conversazione" "Esci dalla stanza" @@ -66,10 +70,16 @@ "Informazioni sulla stanza" "Argomento" "Aggiornamento della stanza…" - "Non ci sono utenti esclusi in questa stanza." + "Non ci sono utenti bannati." + + "%1$d Bannato" + "%1$d Bannati" + + "Controlla l\'ortografia o prova una nuova ricerca" + "Nessun risultato per “%1$s ”" - "%1$d persona" - "%1$d persone" + "%1$d Persona" + "%1$d Persone" "Rimuovi ed escludi" "Rimuovi soltanto" @@ -78,8 +88,13 @@ "Riammetti nella stanza" "Esclusi" "Membri" - "Solo amministratori" - "Amministratori e moderatori" + + "%1$d Invitato" + "%1$d Invitati" + + "In attesa" + "Amministratore" + "Moderatore" "Proprietario" "Membri della stanza" "Riammissione di %1$s" @@ -106,14 +121,15 @@ "Messaggi e contenuti" "Moderatori" "Proprietari" + "Autorizzazioni" "Reimpostare le autorizzazioni" "Una volta reimpostate le autorizzazioni, perderai le impostazioni correnti." "Reimpostare autorizzazioni?" "Ruoli" "Dettagli della stanza" "Ruoli e autorizzazioni" - "Aggiungi l\'indirizzo della stanza" - "Chiunque può chiedere di entrare nella stanza, ma un amministratore o un moderatore dovrà accettare la richiesta." + "Aggiungi indirizzo" + "Chiunque deve richiedere l\'accesso." "Chiedi di entrare" "Sì, attiva la crittografia" "Una volta attivata, la crittografia di una stanza non può essere disattivata, la cronologia dei messaggi sarà visibile solo ai membri della stanza da quando sono stati invitati o da quando sono entrati nella stanza. @@ -123,17 +139,18 @@ Non consigliamo di attivare la crittografia per le stanze che chiunque può trov "Una volta attivata, la crittografia non può essere disattivata." "Crittografia" "Attiva la crittografia end-to-end" - "Chiunque può trovare ed entrare" + "Chiunque può partecipare." "Chiunque" - "Le persone possono partecipare solo se invitate" + "Solo le persone invitate possono entrare." "Solo su invito" - "Accesso alla stanza" - "Gli spazi non sono attualmente supportati" + "Accesso" "Membri dello spazio" - "Avrai bisogno di un indirizzo della stanza per renderla visibile nell\'elenco." - "Indirizzo della stanza" + "Gli spazi non sono attualmente supportati" + "Per renderlo visibile nell\'elenco pubblico, avrai bisogno di un indirizzo." + "Indirizzo" "Consenti la ricerca di questa stanza effettuando una ricerca nell\'elenco delle stanze pubbliche di %1$s" - "Visibile nell\'elenco delle stanze pubbliche" + "Consenti di essere trovato effettuando una ricerca nell\'elenco pubblico." + "Visibile nell\'elenco pubblico" "Chiunque" "Chi può leggere la cronologia messaggi" "Solo membri da quando sono stati invitati" @@ -141,6 +158,7 @@ Non consigliamo di attivare la crittografia per le stanze che chiunque può trov "Gli indirizzi delle stanze sono modi per trovare e accedervi. In questo modo puoi anche condividere facilmente la tua stanze con altri. Puoi scegliere di pubblicare la tua stanza nell\'elenco delle stanza pubbliche dell\'homeserver." "Pubblicazione della stanza" - "Visibilità della stanza" + "Gli indirizzi sono un modo per trovare e accedere a stanze e spazi. Questo ti consente anche di condividerli facilmente con altri." + "Visibilità" "Sicurezza e privacy" diff --git a/features/roomdetails/impl/src/main/res/values-ko/translations.xml b/features/roomdetails/impl/src/main/res/values-ko/translations.xml index c025fdbf49..22f3fe99e6 100644 --- a/features/roomdetails/impl/src/main/res/values-ko/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ko/translations.xml @@ -127,8 +127,8 @@ "초대받은 사용자만 가입할 수 있습니다." "초대 전용" "방 액세스" - "스페이스는 현재 지원되지 않습니다" "스페이스 멤버들" + "스페이스는 현재 지원되지 않습니다" "디렉토리에 표시하려면 방 주소가 필요합니다." "%1$s 공개 방 디렉토리에서 이 방을 검색할 수 있도록 허용합니다" "공개 룸 디렉토리에 표시됨" diff --git a/features/roomdetails/impl/src/main/res/values-nb/translations.xml b/features/roomdetails/impl/src/main/res/values-nb/translations.xml index 4fa2154462..7d23507a8b 100644 --- a/features/roomdetails/impl/src/main/res/values-nb/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-nb/translations.xml @@ -130,8 +130,8 @@ Vi anbefaler ikke å aktivere kryptering for rom som hvem som helst kan finne og "Folk kan bare bli med hvis de er invitert" "Kun for inviterte" "Tilgang til rom" - "Områder støttes ikke for øyeblikket" "Medlemmer av område" + "Områder støttes ikke for øyeblikket" "Du trenger en adresse til rommet for å gjøre det synlig i katalogen." "Tillat at dette rommet blir funnet ved å søke %1$s offentlig romkatalog" "Synlig i offentlig romkatalog" diff --git a/features/roomdetails/impl/src/main/res/values-pl/translations.xml b/features/roomdetails/impl/src/main/res/values-pl/translations.xml index b7382e8d90..a24774c736 100644 --- a/features/roomdetails/impl/src/main/res/values-pl/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-pl/translations.xml @@ -131,8 +131,8 @@ Odradzamy włączanie szyfrowania dla pokoi, które każdy może znaleźć i do "Tylko osoby z zaproszeniem mogą dołączyć" "Tylko zaproszenie" "Dostęp do pokoju" - "Przestrzenie nie są obecnie wspierane" "Członkowie przestrzeni" + "Przestrzenie nie są obecnie wspierane" "Aby pokój był widoczny w katalogu, potrzebny jest adres pokoju." "Adres pokoju" "Zezwól na znalezienie tego pokoju wyszukując %1$s w katalogu pokoi publicznych" diff --git a/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml b/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml index 4eb9da3062..da19da98ed 100644 --- a/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-pt-rBR/translations.xml @@ -1,19 +1,21 @@ - "Você precisará de um endereço de sala para torná-la visível no diretório." - "Endereço da sala" + "Você precisará de um endereço para torná-la visível no diretório." + "Editar endereço" "Ocorreu um erro ao atualizar a configuração de notificação." "Seu servidor-casa não suporta esta opção em salas criptografadas. Você pode não ser notificado em algumas salas." "Enquetes" - "Somente administradores" + "Administradores" "Banir pessoas" "Remover mensagens" - "Convide pessoas e aceite solicitações de entrada" + "Membro" + "Convidar pessoas" + "Gerenciar membros" "Mensagens e conteúdo" - "Administradores e moderadores" - "Remover pessoas e recusar solicitações de entrada" + "Moderador" + "Remover pessoas" "Alterar avatar da sala" - "Editar sala" + "Editar detalhes" "Alterar nome da sala" "Alterar tópico da sala" "Enviar mensagens" @@ -40,7 +42,7 @@ "Criptografado" "Não criptografado" "Sala pública" - "Editar sala" + "Editar detalhes" "Ocorreu um erro desconhecido e as informações não puderam ser alteradas." "Não foi possível atualizar a sala" "As mensagens são protegidas com cadeados. Somente você e os destinatários têm as chaves exclusivas para desbloqueá-los." @@ -48,6 +50,8 @@ "Ocorreu um erro ao carregar as configurações de notificação." "Falha ao silenciar esta sala, tente novamente." "Falha ao desilenciar esta sala. Tente novamente." + "Não feche o aplicativo até terminar." + "Preparando convites…" "Convidar pessoas" "Sair da conversa" "Sair da sala" @@ -66,7 +70,13 @@ "Informação da sala" "Tópico" "Atualizando a sala…" - "Não há usuários banidos nesta sala." + "Não há usuários banidos." + + "%1$d banido" + "%1$d banidos" + + "Confira a ortografia ou tente uma nova busca" + "Nenhum resultado para “%1$s”" "%1$d pessoa" "%1$d pessoas" @@ -78,8 +88,13 @@ "Desbanir da sala" "Banidos" "Membros" - "Somente administradores" - "Administradores e moderadores" + + "%1$d convidado" + "%1$d convidados" + + "Pendente" + "Administradores" + "Moderador" "Proprietário" "Membros da sala" "Desbanindo %1$s" @@ -106,14 +121,15 @@ "Mensagens e conteúdo" "Moderadores" "Proprietários" + "Permissões" "Redefinir permissões" "Depois de redefinir as permissões, você perderá as configurações atuais." "Redefinir permissões?" "Cargos" "Detalhes da sala" "Cargos e permissões" - "Adicionar endereço da sala" - "Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou moderador terá que aceitar o pedido." + "Adicionar endereço" + "Qualquer um pode pedir acesso, mas um administrador terá que aceitar o pedido." "Pedir para entrar" "Sim, ativar a criptografia" "Uma vez ativada, a criptografia de uma sala não pode ser desativada. O histórico de mensagens só será visível para os membros da sala desde que foram convidados ou desde que entraram na sala. @@ -123,16 +139,18 @@ Não recomendamos que você ative a criptografia para salas que qualquer pessoa "Uma vez ativada, a criptografia não poderá ser desativada." "Criptografia" "Ativar a criptografia de ponta a ponta" - "Qualquer um pode encontrar e entrar" + "Qualquer um pode entrar" "Qualquer pessoa" - "As pessoas só podem participar se forem convidadas" - "Somente para convidados" - "Acesso à sala" - "No momento, não há suporte aos espaços" + "Apenas pessoas convidadas podem entrar." + "Privado" + "Acesso" "Membros do espaço" - "Você precisará de um endereço de sala para torná-la visível no diretório." + "No momento, não há suporte aos espaços" + "Você precisará de um endereço para torná-la visível no diretório." + "Endereço publicado" "Permitir que esta sala seja encontrada pesquisando diretório de salas públicas de %1$s" - "Visível no diretório de salas públicas" + "Permite que seja encontrada ao buscar no diretório público." + "Visível no diretório público" "Qualquer pessoa" "Quem pode ler o histórico" "Somente membros, desde que foram convidados" @@ -140,5 +158,7 @@ Não recomendamos que você ative a criptografia para salas que qualquer pessoa "Os endereços das salas são formas de encontrar e acessar as salas. Isso também garante que você possa compartilhar facilmente sua sala com outras pessoas. Você pode optar por publicar sua sala no diretório público de salas do seu servidor-casa." "Publicação da sala" + "Os endereços das salas são formas de encontrar e acessar as salas. Isso também garante que você possa compartilhá-las facilmente com outras pessoas." + "Visibilidade" "Segurança e privacidade" diff --git a/features/roomdetails/impl/src/main/res/values-pt/translations.xml b/features/roomdetails/impl/src/main/res/values-pt/translations.xml index 7f9aca6ea1..b682c0597d 100644 --- a/features/roomdetails/impl/src/main/res/values-pt/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-pt/translations.xml @@ -130,8 +130,8 @@ Não recomendamos ativar a cifragem em salas que qualquer pessoa possa encontrar "Só é possível entrar tendo um convite" "Apenas por convite" "Acesso à sala" - "Os espaços ainda não estão implementados" "Membros do espaço" + "Os espaços ainda não estão implementados" "É necessário um endereço para tornar a sala visível no diretório." "Endereço da sala" "Permite que esta sala seja encontrada através do diretório público do %1$s." diff --git a/features/roomdetails/impl/src/main/res/values-ro/translations.xml b/features/roomdetails/impl/src/main/res/values-ro/translations.xml index 682f312c84..f0c43e53a5 100644 --- a/features/roomdetails/impl/src/main/res/values-ro/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ro/translations.xml @@ -130,8 +130,8 @@ Nu recomandăm activarea criptării pentru camerele pe care oricine le poate gă "Persoanele se pot alătura numai dacă invitate" "Doar pe bază de invitație" "Acces la cameră" - "Spațiile nu sunt momentan suportate." "Membrii spațiului" + "Spațiile nu sunt momentan suportate." "Veți avea nevoie de o adresă de cameră pentru a o face vizibilă în director." "Permiteți găsirea acestei camere prin căutarea în directorul de camere publice al %1$s" "Vizibilă în directorul de camere publice" diff --git a/features/roomdetails/impl/src/main/res/values-ru/translations.xml b/features/roomdetails/impl/src/main/res/values-ru/translations.xml index 324caed3dc..47de4c388c 100644 --- a/features/roomdetails/impl/src/main/res/values-ru/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-ru/translations.xml @@ -137,8 +137,8 @@ "Присоединиться могут только приглашенные люди." "Только по приглашению" "Доступ" - "Пространства в настоящее время не поддерживаются." "Участники пространства" + "Пространства в настоящее время не поддерживаются." "Вам понадобится адрес комнаты, чтобы сделать ее видимой в каталоге." "Адрес" "Опубликовать %1$s в каталоге публичных комнат" diff --git a/features/roomdetails/impl/src/main/res/values-sk/translations.xml b/features/roomdetails/impl/src/main/res/values-sk/translations.xml index 662a7c166a..477b419788 100644 --- a/features/roomdetails/impl/src/main/res/values-sk/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-sk/translations.xml @@ -131,8 +131,8 @@ To môže brániť správnemu fungovaniu robotov a premostení. Neodporúčame p "Ľudia sa môžu pripojiť len vtedy, ak sú pozvaní" "Iba na pozvánku" "Prístup do miestnosti" - "Priestory momentálne nie sú podporované" "Členovia priestoru" + "Priestory momentálne nie sú podporované" "Budete potrebovať adresu miestnosti, aby bola viditeľná v adresári." "Adresa miestnosti" "Umožniť vyhľadanie tejto miestnosti v adresári verejných miestností %1$s" diff --git a/features/roomdetails/impl/src/main/res/values-sv/translations.xml b/features/roomdetails/impl/src/main/res/values-sv/translations.xml index 8e2df0138e..2dc590c2f4 100644 --- a/features/roomdetails/impl/src/main/res/values-sv/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-sv/translations.xml @@ -128,8 +128,8 @@ Vi rekommenderar inte att aktivera kryptering för rum som vem som helst kan hit "Användare kan bara gå med om de är inbjudna" "Endast inbjudan" "Tillgång till rum" - "Utrymmen stöds för närvarande inte" "Utrymmesmedlemmar" + "Utrymmen stöds för närvarande inte" "Du behöver en rumsadress för att göra den synlig i katalogen." "Tillåt att detta rum hittas genom att söka i den offentliga rumskatalogen på %1$s" "Synlig i katalogen för offentliga rum" diff --git a/features/roomdetails/impl/src/main/res/values-tr/translations.xml b/features/roomdetails/impl/src/main/res/values-tr/translations.xml index 11201d0da0..01cac3a6cb 100644 --- a/features/roomdetails/impl/src/main/res/values-tr/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-tr/translations.xml @@ -120,8 +120,8 @@ Herkesin bulabileceği ve katılabileceği odalar için şifrelemenin etkinleşt "İnsanlar yalnızca davet edildiklerinde katılabilirler" "Yalnızca davet" "Oda Erişimi" - "Alanlar şu anda desteklenmiyor" "Alan üyeleri" + "Alanlar şu anda desteklenmiyor" "Dizinde görünür hale getirmek için bir oda adresine ihtiyacınız olacak." "Oda adresi" "Bu odanın %1$s genel oda dizininde arama yapılarak bulunmasına izin verin" diff --git a/features/roomdetails/impl/src/main/res/values-uk/translations.xml b/features/roomdetails/impl/src/main/res/values-uk/translations.xml index 34663f9db9..57a604bfe8 100644 --- a/features/roomdetails/impl/src/main/res/values-uk/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-uk/translations.xml @@ -129,8 +129,8 @@ "Люди можуть приєднатися, лише якщо їх запросили" "Лише запрошені" "Доступ до кімнати" - "Простори наразі не підтримуються" "Учасники простору" + "Простори наразі не підтримуються" "Вам знадобиться адреса кімнати, щоб зробити її видимою в каталозі." "Адреса кімнати" "Дозвольте, щоб цю кімнату можна було знайти за допомогою пошуку в каталозі загальнодоступних кімнат %1$s " diff --git a/features/roomdetails/impl/src/main/res/values-uz/translations.xml b/features/roomdetails/impl/src/main/res/values-uz/translations.xml index a95af68769..401d015735 100644 --- a/features/roomdetails/impl/src/main/res/values-uz/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-uz/translations.xml @@ -1,5 +1,7 @@ + "Katalogda ko‘rinadigan qilish uchun xona manzili kerak bo‘ladi." + "Xona manzili" "Bildirishnoma sozlamalarini yangilashda xatolik yuz berdi." "Uy serveringiz shifrlangan xonalarda ushbu imkoniyatni qoʻllab-quvvatlamaydi, shuning uchun baʼzi xonalardagi xabarlarni olmasligingiz mumkin." "Soʻrovnomalar" @@ -18,13 +20,17 @@ "Administratorlarni tahrirlash" "Bu amalni bekor qila olmaysiz. Siz foydalanuvchini o‘zingiz bilan bir xil quvvat darajasiga ega bo‘lishga undayapsiz." "Admin qo‘shilsinmi?" + "Bu amalni bekor qila olmaysiz. Siz egalikni tanlangan foydalanuvchilarga o‘tkazmoqdasiz. Tark etsangiz, bu doimiy bo‘ladi." + "Egalik huquqini o‘tkazasizmi?" "Pastga tushirish" "Siz oʻzingizni imtiyozlardan mahrum qilayotganingiz sababli, bu o‘zgarishni bekor qila olmaysiz. Agar xonadagi so‘nggi imtiyozli foydalanuvchi bo‘lsangiz, imtiyozlarni qayta tiklash imkonsiz bo‘ladi." "O‘z darajangizni pasaytirmoqchimisiz?" "%1$s (Jarayonda)" "(Kutilmoqda)" "Administratorlar avtomatik ravishda moderator imtiyozlariga ega" + "Egalar avtomatik ravishda administrator huquqlariga ega." "Moderatorlarni tahrirlash" + "Egalarni tanlang" "Adminlar" "Moderatorlar" "Azolar" @@ -45,13 +51,16 @@ "Odamlarni taklif qiling" "Suhbatni tark etish" "Xonani tark etish" + "Media va fayllar" "Maxsus" "Standart" "Bildirishnomalar" "Qadalgan xabarlar" "Profil" + "Qo‘shilish uchun so‘rovlar" "Rollar va ruxsatlar" "Xona nomi" + "Xavfsizlik va maxfiylik" "Xavfsizlik" "Xonani baham ko\'ring" "Xona haqida maʼlumot" @@ -66,10 +75,12 @@ "Faqat aʻzoni olib tashlash" "Taqiqni bekor qilish" "Agar taklif qilinsa, ular bu xonaga qayta qo‘shilishlari mumkin." + "Xonadan taqiqni olib tashlash" "Taqiqlangan" "Azolar" "Faqat adminlar" "Adminlar va moderatorlar" + "Egasi" "Xona a\'zolari" "Taqiqni bekor qilish %1$s" "Moslashtirilgan sozlamalarga ruxsat bering" @@ -87,20 +98,46 @@ "Faqat eslatmalar va kalit so\'zlar" "Bu xonada menga xabar bering" "Adminlar" + "Adminlar va egalari" "Rolimni o‘zgartirish" "Aʼzolikka tushirish" "Moderatorga pasaytirish" "Aʻzo moderatsiyasi" "Xabarlar va kontent" "Moderatorlar" + "Egalari" "Ruxsatlarni tiklash" "Ruxsatlarni asliga qaytargach, joriy sozlamalarni yoʻqotasiz." "Ruxsatlar asliga qaytarilsinmi?" "Rollar" "Xona tafsilotlari" "Rollar va ruxsatlar" + "Xona manzilini kiritish" + "Xonaga qo‘shilishni istalgan kishi so‘rashi mumkin, lekin administrator yoki moderator so‘rovni qabul qilishi kerak" "Qo‘shilishni so‘rang" + "Ha, shifrlashni yoqish" + "Yoqilgandan so‘ng, xona uchun shifrlashni o‘chirib bo‘lmaydi. Xabarlar tarixi faqat xona a’zolari taklif qilinganidan yoki xonaga qo‘shilganidan keyingi davrdan boshlab ko‘rinadi. Xona a’zolaridan tashqari hech kim xabarlarni o‘qiy olmaydi. Bu botlar va ko‘priklarning to‘g‘ri ishlashiga to‘sqinlik qilishi mumkin. +Shu sababli, har kim topishi va qo‘shilishi mumkin bo‘lgan xonalar uchun shifrlashni yoqishni tavsiya etmaymiz." + "Shifrlash yoqilsinmi?" + "Yoqilgandan keyin shifrlashni faolsizlantirish imkonsiz." "Shifrlash" + "End-to-end shifrlashni yoqish" + "Istalgan kishi topishi va qo‘shilishi mumkin" "Har kim" + "Odamlar faqat taklif qilingan taqdirdagina qo‘shilishi mumkin" + "Faqat taklif qilish" + "Xonaga kirish huquqi" + "Maydon a’zolari" + "Hozirda maydonlar qo‘llab-quvvatlanmaydi" + "Katalogda ko‘rinadigan qilish uchun xona manzili kerak bo‘ladi." + "Bu xonani %1$s umumiy xonalar ro‘yxatidan qidirib topish imkoniyatini berish" + "Umumiy xona ro‘yxatida ko‘rinadi" "Har kim" + "Tarixni kim o‘qiy oladi" + "Taklif qilinganidan buyon faqat a’zolar" + "A’zolar faqat bu parametr tanlanganidan keyin" + "Xona manzillari xonalarni topish va ularga kirish usullaridir. Bu shuningdek xonangizni boshqalar bilan oson ulashish imkonini beradi. +Xonangizni o‘z homeserveringizning ommaviy xonalar ro‘yxatida e’lon qilishni tanlashingiz mumkin." + "xona nashriyoti" + "Xavfsizlik va maxfiylik" diff --git a/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml b/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml index 9de710e576..0332c0ffd5 100644 --- a/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-zh-rTW/translations.xml @@ -135,8 +135,8 @@ "僅受邀者才能加入。" "僅限邀請" "存取權" - "目前不支援空間" "空間成員" + "目前不支援空間" "您需要地址才能在公開目錄中顯示。" "地址" "允許透過搜尋 %1$s 公開聊天室目錄找到此聊天室" diff --git a/features/roomdetails/impl/src/main/res/values-zh/translations.xml b/features/roomdetails/impl/src/main/res/values-zh/translations.xml index a373e5d3c4..f925bdca2a 100644 --- a/features/roomdetails/impl/src/main/res/values-zh/translations.xml +++ b/features/roomdetails/impl/src/main/res/values-zh/translations.xml @@ -68,7 +68,7 @@ "聊天室信息" "主题" "正在更新聊天室……" - "此聊天室里没有被封禁的用户。" + "没有被封禁的用户。" "%1$d 人" @@ -129,8 +129,8 @@ "只有受邀者才能加入" "仅限邀请" "房间访问权限" - "目前不支持空间" "空间成员" + "目前不支持空间" "你需要房间地址才能使其在目录中可见。" "房间地址" "允许通过搜索 %1$s 的公共房间目录来发现此房间" diff --git a/features/roomdetails/impl/src/main/res/values/localazy.xml b/features/roomdetails/impl/src/main/res/values/localazy.xml index 2f57c250f1..c582f6f6fb 100644 --- a/features/roomdetails/impl/src/main/res/values/localazy.xml +++ b/features/roomdetails/impl/src/main/res/values/localazy.xml @@ -141,11 +141,15 @@ We do not recommend enabling encryption for rooms that anyone can find and join. "Enable end-to-end encryption" "Anyone can join." "Anyone" + "Choose which spaces’ members can join this room without an invitation. %1$s" + "Manage spaces" "Only invited people can join." "Invite only" "Access" - "Spaces are not currently supported" + "Anyone in authorized spaces can join." + "Anyone in %1$s can join." "Space members" + "Spaces are not currently supported" "You’ll need an address in order to make it visible in the public directory." "Address" "Allow for this room to be found by searching %1$s public room directory" diff --git a/features/roommembermoderation/impl/src/main/res/values-cs/translations.xml b/features/roommembermoderation/impl/src/main/res/values-cs/translations.xml index 20fc68c391..a7d8966384 100644 --- a/features/roommembermoderation/impl/src/main/res/values-cs/translations.xml +++ b/features/roommembermoderation/impl/src/main/res/values-cs/translations.xml @@ -4,10 +4,12 @@ "Vykázat" "Nebudou se moci znovu připojit k této místnosti, pokud budou pozváni." "Jste si jisti, že chcete vykázat tohoto člena?" + "Pokud budou pozváni, nebudou moci vstoupit do tohoto prostoru, ale stále si zachovají členství ve všech místnostech nebo podprostorech." "Vykazování %1$s" "Odebrat" "Pokud budou pozváni, budou se moci do této místnosti znovu připojit." "Opravdu chcete tohoto člena odebrat?" + "Pokud budou pozváni, budou moci vstoupit do tohoto prostoru a zachovají si členství ve všech místnostech nebo podprostorech." "Zobrazit profil" "Odebrat uživatele" "Odebrat člena a zakázat mu připojení v budoucnu?" diff --git a/features/roommembermoderation/impl/src/main/res/values-fi/translations.xml b/features/roommembermoderation/impl/src/main/res/values-fi/translations.xml index 4c93f73780..1eb78cd2ae 100644 --- a/features/roommembermoderation/impl/src/main/res/values-fi/translations.xml +++ b/features/roommembermoderation/impl/src/main/res/values-fi/translations.xml @@ -4,12 +4,14 @@ "Anna porttikielto" "He eivät voi enää liittyä tähän huoneeseen, jos heidät kutsutaan." "Haluatko varmasti antaa tälle jäsenelle porttikiellon?" + "He eivät voi liittyä tähän tilaan uudelleen, vaikka heidät kutsuttaisiin, mutta he säilyttävät jäsenyytensä muissa huoneissa tai alitiloissa." "Annetaan porttikieltoa käyttäjälle %1$s" "Poista" "He voivat liittyä tähän huoneeseen uudelleen, jos heidät kutsutaan." "Haluatko varmasti poistaa tämän jäsenen?" + "He voivat liittyä tähän tilaan uudelleen, jos heidät kutsutaan, ja he säilyttävät jäsenyytensä kaikissa huoneissa tai alitiloissa." "Näytä profiili" - "Poista huoneesta" + "Poista käyttäjä" "Poistetaanko jäsen huoneesta ja kielletäänkö heitä liittymästä tulevaisuudessa?" "Poistetaan käyttäjää %1$s huoneesta…" "Poista porttikielto huoneesta" diff --git a/features/roommembermoderation/impl/src/main/res/values-it/translations.xml b/features/roommembermoderation/impl/src/main/res/values-it/translations.xml index 7791d04546..4e423e2951 100644 --- a/features/roommembermoderation/impl/src/main/res/values-it/translations.xml +++ b/features/roommembermoderation/impl/src/main/res/values-it/translations.xml @@ -4,12 +4,14 @@ "Escludi" "Non potrà entrare nuovamente in questa stanza se invitato." "Vuoi davvero escludere questo membro?" + "Se invitati, non potranno più unirsi a questo spazio, ma manterranno comunque la loro iscrizione a tutte le stanze o sottospazi." "Esclusione di %1$s" "Rimuovi" "Potrà entrare nuovamente in questa stanza se invitato." "Sei sicuro di voler rimuovere questo membro?" + "Potranno unirsi nuovamente a questo spazio se invitati e manterranno comunque la loro iscrizione a tutte le stanze o sottospazi." "Visualizza profilo" - "Rimuovi dalla stanza" + "Rimuovi utente" "Rimuovere e vietare l\'accesso in futuro?" "Rimozione di %1$s…" "Riammetti nella stanza" diff --git a/features/roommembermoderation/impl/src/main/res/values-pt-rBR/translations.xml b/features/roommembermoderation/impl/src/main/res/values-pt-rBR/translations.xml index 4cbc0ba081..5a356e18f6 100644 --- a/features/roommembermoderation/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/roommembermoderation/impl/src/main/res/values-pt-rBR/translations.xml @@ -4,12 +4,14 @@ "Banir" "Essa pessoa não poderá entrar nesta sala novamente se for convidada." "Tem certeza de que quer banir este membro?" + "Eles não poderão mais entrar no espaço novamente se forem convidados, mas manterão sua participação em quaisquer salas e sub-espaços." "Banindo %1$s" "Remover" "Esta pessoa poderá entrar nesta sala novamente se for convidada." "Tem certeza de que deseja remover este membro?" + "Eles poderão entrar no espaço novamente se convidados, e manterão sua participação em quaisquer salas e sub-espaços." "Ver perfil" - "Remover da sala" + "Remover usuário" "Remover membro e banir de entrar novamente no futuro?" "Removendo %1$s…" "Desbanir da sala" diff --git a/features/roommembermoderation/impl/src/main/res/values-uz/translations.xml b/features/roommembermoderation/impl/src/main/res/values-uz/translations.xml index d7b09f0e8d..90dfae8ce3 100644 --- a/features/roommembermoderation/impl/src/main/res/values-uz/translations.xml +++ b/features/roommembermoderation/impl/src/main/res/values-uz/translations.xml @@ -5,11 +5,16 @@ "Taklif qilingan taqdirda ham, ular bu xonaga boshqa qo‘shila olmaydilar." "Haqiqatan ham bu aʼzoni taqiqlamoqchimisiz?" "Taqiqlash %1$s" + "Oʻchirish" "Agar taklif qilinsa, ular bu xonaga qayta qo‘shilishlari mumkin." + "Haqiqatan ham bu a’zoni olib tashlaysizmi?" "Profilni koʻrish" "Xonadan olib tashlash" "Aʻzo oʻchirilsinmi va kelgusida qoʻshilish taqiqlansinmi?" "Oʻchirish %1$s …" + "Xonadan taqiqni olib tashlash" "Taqiqni bekor qilish" + "Agar taklif qilinsa, ular xonaga yana qo‘shilishlari mumkin" + "Haqiqatan ham bu a’zoni blokdan chiqarmoqchimisiz?" "Taqiqni bekor qilish %1$s" diff --git a/features/roommembermoderation/impl/src/main/res/values-zh/translations.xml b/features/roommembermoderation/impl/src/main/res/values-zh/translations.xml index a27d2ded05..aa8b2e3df8 100644 --- a/features/roommembermoderation/impl/src/main/res/values-zh/translations.xml +++ b/features/roommembermoderation/impl/src/main/res/values-zh/translations.xml @@ -4,12 +4,14 @@ "封禁" "即使受到邀请,他们也无法再次加入聊天室。" "您确定要封禁该成员吗?" + "即使再次受邀,他们也无法加入这个空间,但他们仍将保留其在任何房间或子空间的成员资格。" "封禁 %1$s" "移除" "如果受到邀请,他们可以重新加入聊天室。" "您确定要移除此成员吗?" + "如果受到邀请,他们将能够再次加入这个空间,并且他们仍将保留其在任何房间或子空间的成员资格。" "查看个人资料" - "从聊天室移除" + "移除用户" "删除成员并禁止重新加入?" "正在移除 %1$s……" "从房间取消解封" diff --git a/features/securityandprivacy/impl/src/main/res/values-be/translations.xml b/features/securityandprivacy/impl/src/main/res/values-be/translations.xml index 166afb9568..a1e1745100 100644 --- a/features/securityandprivacy/impl/src/main/res/values-be/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-be/translations.xml @@ -1,5 +1,6 @@ "Папрасіце далучыцца" + "Хто заўгодна" "Хто заўгодна" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-bg/translations.xml b/features/securityandprivacy/impl/src/main/res/values-bg/translations.xml index 7ae4ba25cf..9917a7146f 100644 --- a/features/securityandprivacy/impl/src/main/res/values-bg/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-bg/translations.xml @@ -4,20 +4,19 @@ "Да, включване на шифроването" "Да се включи ли шифроването?" "Веднъж включено, шифроването не може да бъде изключено." + "Шифроване" "Включване на шифроване от край до край" "Всеки може да намери и да се присъедини" + "Всеки" "Хората могат да се присъединят само ако са поканени" "Само с покана" "Достъп до стаята" - "Пространствата в момента не се поддържат" "Членове на пространството" - "Ще ви е необходим адрес на стаята, за да я направите видима в директорията на стаите." + "Пространствата в момента не се поддържат" "Видима в директорията на обществените стаи" + "Всеки" "Кой може да чете историята" "Само за членове откакто са поканени" "Само за членове от избирането на тази опция" "Защита и поверителност" - "Шифроване" - "Всеки" - "Видимост на стаята" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-cs/translations.xml b/features/securityandprivacy/impl/src/main/res/values-cs/translations.xml index 299ac2b643..a70ccdbf72 100644 --- a/features/securityandprivacy/impl/src/main/res/values-cs/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-cs/translations.xml @@ -1,38 +1,41 @@ - "Aby byla místnost v adresáři viditelná, je třeba zadat její adresu." - "Adresa místnosti" - "Přidat adresu místnosti" - "Kdokoli může požádat o vstup do místnosti, ale správce nebo moderátor bude muset žádost přijmout." + "Budete potřebovat adresu místnosti, aby byla viditelná v adresáři místností." + "Upravit adresu" + "Přidat adresu" + "Všichni musí požádat o přístup." + "Požádat o připojení" "Ano, povolit šifrování" "Po aktivaci nelze šifrování místnosti deaktivovat. Historie zpráv bude viditelná pouze pro členy místnosti od doby, kdy byli pozváni nebo od té doby, co do místnosti vstoupili. Nikdo kromě členů místnosti nebude moci číst zprávy. To může bránit správnému fungování robotů a propojení. Nedoporučujeme povolovat šifrování pro místnosti, které může kdokoli najít a vstoupit do nich." "Povolit šifrování?" "Jakmile je povoleno, šifrování nelze zakázat." + "Šifrování" "Povolit koncové šifrování" - "Každý může najít a vstoupit" + "Vstoupit může kdokoli." "Kdokoliv" - "Lidé mohou vstoupit, pouze pokud jsou pozváni" + "Vyberte, kteří členové prostorů se k této místnosti mohou připojit bez pozvánky. %1$s" + "Vstoupit mohou pouze pozvaní lidé." "Pouze pro zvané" - "Přístup do místnosti" - "Prostory nejsou aktuálně podporovány" + "Přístup" + "Vstoupit může kdokoli z autorizovaných prostorů." + "Vstoupit může kdokoli v %1$s." "Členové prostoru" + "Prostory nejsou aktuálně podporovány" "Budete potřebovat adresu místnosti, aby byla viditelná v adresáři místností." - "Adresa místnosti" + "Adresa" "Umožněte nalezení této místnosti prohledáním adresáře veřejných místností na %1$s" - "Viditelné v adresáři veřejných místností" + "Umožnit nalezení vyhledáváním ve veřejném adresáři." + "Viditelné ve veřejném adresáři" + "Kdokoliv" "Kdo může číst historii" "Pouze členové od té doby, co byli pozváni" "Pouze členové od výběru této možnosti" "Adresy místností představují způsoby, jak najít místnosti a získat k nim přístup. Díky tomu můžete svoji místnost snadno sdílet s ostatními. Můžete se rozhodnout publikovat svou místnost ve veřejném adresáři místnosti vašeho domovského serveru." "Publikování místnosti" - "Adresy místností představují způsoby, jak najít místnosti a získat k nim přístup. Díky tomu můžete svoji místnost snadno sdílet s ostatními. -Adresa je také vyžadována pro zobrazení místnosti v adresáři veřejných místností %1$s." + "Adresy slouží k vyhledávání a přístupu do místností a prostorů. Díky tomu je také můžete snadno sdílet s ostatními." + "Viditelnost" "Zabezpečení a soukromí" - "Požádat o připojení" - "Šifrování" - "Kdokoliv" - "Viditelnost místnosti" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-cy/translations.xml b/features/securityandprivacy/impl/src/main/res/values-cy/translations.xml index 249fa6a1da..ce812b0f83 100644 --- a/features/securityandprivacy/impl/src/main/res/values-cy/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-cy/translations.xml @@ -4,35 +4,33 @@ "Cyfeiriad yr ystafell" "Ychwanegu cyfeiriad ystafell" "Gall unrhyw un ofyn am gael ymuno â\'r ystafell ond bydd rhaid i weinyddwr neu gymedrolwr dderbyn y cais." + "Gofyn i gael ymuno" "Iawn, galluogi amgryptio" "Unwaith y bydd wedi\'i alluogi, does dim modd analluogi amgryptio ar gyfer ystafell, dim ond ar gyfer aelodau\'r ystafell y bydd hanes neges yn weladwy ers iddyn nhw gael eu gwahodd neu ers iddyn nhw ymuno â\'r ystafell. Fydd neb ar wahân i aelodau\'r ystafell yn gallu darllen negeseuon. Gall hyn atal botiau a phontydd i weithio\'n gywir. Nid ydym yn argymell galluogi amgryptio ar gyfer ystafelloedd y gall unrhyw un ddod o hyd iddynt ac ymuno â nhw." "Galluogi amgryptio?" "Unwaith y bydd wedi\'i alluogi, does dim modd analluogi amgryptio." + "Amgryptiad" "Galluogi amgryptio o\'r dechrau i\'r diwedd" "Gall unrhyw un ddod o hyd iddo ac ymuno" "Unrhyw un" "Dim ond os cawn nhw wahoddiad gall pobl ymuno" "Gwahoddiad yn unig" "Mynediad ystafell" - "Nid yw gofodau\'n cael eu cefnogi ar hyn o bryd" "Aelodau gofod" - "Bydd angen cyfeiriad ystafell arnoch er mwyn ei wneud yn weladwy yn y cyfeiriadur ystafelloedd." + "Nid yw gofodau\'n cael eu cefnogi ar hyn o bryd" + "Bydd angen cyfeiriad ystafell arnoch i\'w wneud yn weladwy yn y cyfeiriadur." "Cyfeiriad yr ystafell" "Caniatáu i\'r ystafell hon gael ei chanfod trwy chwilio cyfeiriadur ystafelloedd cyhoeddus %1$s" "Gweladwy yn y cyfeiriadur ystafelloedd cyhoeddus" + "Unrhyw un" "Pwy all ddarllen hanes" "Yn aelodau ond dim ond ers cael eu gwahodd" "Yn aelodau dim ond ers dewis y dewis hwn" "Mae cyfeiriadau ystafelloedd yn ffyrdd o ddod o hyd i ystafelloedd a chael mynediad iddyn nhw. Mae hyn hefyd yn sicrhau y gallwch chi rannu\'ch ystafell yn hawdd ag eraill. Gallwch ddewis cyhoeddi eich ystafell yng ngweinydd cartref eich cyfeiriadur ystafelloedd cyhoeddus." "Cyhoeddi ystafell" - "Mae cyfeiriadau ystafelloedd yn ffyrdd o ddod o hyd i ystafelloedd a chael mynediad iddyn nhw. Mae hyn hefyd yn sicrhau y gallwch chi rannu\'ch ystafell yn hawdd ag eraill. -Mae angen y cyfeiriad hefyd i wneud yr ystafell yn weladwy yng nghyfeiriadur ystafell gyhoeddus %1$s." - "Diogelwch a phreifatrwydd" - "Gofyn i gael ymuno" - "Amgryptiad" - "Unrhyw un" "Gwelededd yr ystafell" - \ No newline at end of file + "Diogelwch a phreifatrwydd" + diff --git a/features/securityandprivacy/impl/src/main/res/values-da/translations.xml b/features/securityandprivacy/impl/src/main/res/values-da/translations.xml index 1a8a9046b6..46a20980bd 100644 --- a/features/securityandprivacy/impl/src/main/res/values-da/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-da/translations.xml @@ -4,33 +4,31 @@ "Rummets adresse" "Tilføj adresse på rum" "Alle kan bede om at deltage i lokalet, men en administrator eller moderator skal acceptere anmodningen." + "Spørg om at deltage" "Ja, aktivér kryptering" "Når det først er aktiveret, kan kryptering for et rum ikke deaktiveres igen. Beskedhistorik vil kun være synlig for rummedlemmer, siden de blev inviteret, eller siden de blev medlem af rummet. Ingen udover medlemmer af rummet vil være i stand til at læse beskeder. Dette kan forhindre bots og broer i at fungere korrekt. Vi anbefaler ikke at aktivere kryptering for rum, som alle kan finde og deltage i." "Aktivér kryptering?" "Når kryptering først er aktiveret, kan den ikke deaktiveres igen." + "Kryptering" "Aktivér end-to-end-kryptering" "Alle kan finde og deltage" + "Enhver" "Andre kan kun deltage, hvis de bliver inviteret" "Kun med invitation" "Adgang til rummet" - "Grupper understøttes ikke i øjeblikket" "Medlemmer af gruppen" - "Du skal bruge en adresse til rummet, for at gøre den synlig i rum-registeret." + "Grupper understøttes ikke i øjeblikket" + "Du skal bruge en rum-adresse for at gøre den synlig i kataloget." "Tillad, at dette rum kan findes ved at søge i %1$s fortegnelse over offentlige rum" "Synlig i det offentlige register over rum" + "Enhver" "Hvem kan læse historikken?" "Kun medlemmer, efter de blev inviteret" "Kun medlemmer siden valg af denne mulighed" "Rum-adresser er en måde at finde og få adgang til værelser på. Dette sikrer også, at du nemt kan dele dit rum med andre. Du kan vælge at offentliggøre dit rum i din hjemmeservers offentlige katalog over rum." "Udgivelse af rum" - "Rum-adresser er måder at finde og få adgang til rum på. Dette sikrer også, at du nemt kan dele dit rum med andre. -Adressen er også påkrævet for at gøre rummet synligt i det %1$s offentlige register." "Sikkerhed og privatliv" - "Spørg om at deltage" - "Kryptering" - "Enhver" - "Rummets synlighed" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-de/translations.xml b/features/securityandprivacy/impl/src/main/res/values-de/translations.xml index cc311a70f4..c37481560d 100644 --- a/features/securityandprivacy/impl/src/main/res/values-de/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-de/translations.xml @@ -4,35 +4,33 @@ "Chat-Adresse" "Chat-Adresse hinzufügen" "Jeder kann den Beitritt zum Chat anfragen, aber ein Admin oder Moderator müssen die Anfrage akzeptieren." + "Beitritt beantragen" "Ja, Verschlüsselung aktivieren" "Einmal angeschaltet kann die Verschlüsselung für einen Chat nicht mehr deaktiviert werden. Der Nachrichtenverlauf ist für Mitglieder nur sichtbar, seit sie eingeladen wurden oder dem Chat beigetreten sind. Niemand außer den Chat Mitgliedern kann Nachrichten lesen. Dies kann verhindern, dass Bots und Bridges richtig funktionieren. Wir empfehlen keine Verschlüsselung für Chats zu aktivieren, die jeder finden und denen jeder beitreten darf." "Verschlüsselung aktivieren?" "Einmal angeschaltet kann die Verschlüsselung nicht mehr deaktiviert werden." + "Verschlüsselung" "Ende-zu-Ende-Verschlüsselung aktivieren" "Jeder kann diesen Chat finden und ihm beitreten" - "Alle" + "Jeder" "Personen können nur beitreten, wenn sie eingeladen werden." "Nur auf Einladung" "Chat Zugang" - "Spaces werden zur Zeit nicht unterstützt." "Spacemitglieder" + "Spaces werden zur Zeit nicht unterstützt." "Du benötigst eine Chat-Adresse, um den Chat im Verzeichnis sichtbar zu machen." "Chatroomadresse" "Erlaube das Auffinden dieses Chats durch Suche im öffentlichen Verzeichnis von %1$s" "Sichtbar im öffentlichen Verzeichnis" + "Jeder" "Wer hat Zugriff auf den Nachrichtenverlauf" "Nur Mitglieder, aber erst seit deren Einladung" "Nur Mitglieder seit Auswahl dieser Option" "Chat-Adressen machen es möglich, Chats zu finden und ihnen beizutreten. Dies erleichtert es, Chats mit anderen zu teilen. Auf Wunsch kannst du deinen Chat im öffentlichen Verzeichnis deines Homeservers veröffentlichen." "Veröffentlichung von Chats" - "Chat-Adressen machen es möglich, Chats zu finden und ihnen beizutreten. Dies erleichtert es, Chats mit anderen zu teilen. -Die Adresse ist auch erforderlich, um den Chat im öffentlichen Verzeichnis von %1$s zu veröffentlichen." + "Chatroomsichtbarkeit." "Sicherheit & Datenschutz" - "Beitritt beantragen" - "Verschlüsselung" - "Jeder" - " Sichtbarkeit des Chats" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-el/translations.xml b/features/securityandprivacy/impl/src/main/res/values-el/translations.xml index 8e2f0ad361..1946bae8b2 100644 --- a/features/securityandprivacy/impl/src/main/res/values-el/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-el/translations.xml @@ -4,34 +4,31 @@ "Διεύθυνση αίθουσας" "Προσθήκη διεύθυνσης αίθουσας" "Οποιοσδήποτε μπορεί να ζητήσει να συμμετάσχει στην αίθουσα, αλλά ένας διαχειριστής ή συντονιστής θα πρέπει να αποδεχτεί το αίτημα." + "Αίτημα συμμετοχής" "Ναι, ενεργοποιήστε την κρυπτογράφηση" "Μόλις ενεργοποιηθεί, η κρυπτογράφηση για μια αίθουσα δεν μπορεί να απενεργοποιηθεί, το ιστορικό μηνυμάτων θα είναι ορατό μόνο για τα μέλη της αίθουσας από τότε που προσκλήθηκαν ή από τότε που συμμετείχαν στην αίθουσα. Κανείς άλλος εκτός από τα μέλη της αίθουσας δεν θα μπορεί να διαβάσει τα μηνύματα. Αυτό μπορεί να εμποδίσει τη σωστή λειτουργία των bots και των γεφυρών. Δεν συνιστούμε την ενεργοποίηση της κρυπτογράφησης για αίθουσες που μπορεί να βρει και να συμμετάσχει ο καθένας." "Ενεργοποίηση κρυπτογράφησης;" "Μόλις ενεργοποιηθεί, η κρυπτογράφηση δεν μπορεί να απενεργοποιηθεί." + "Κρυπτογράφηση" "Ενεργοποίηση κρυπτογράφησης από άκρο σε άκρο" "Οποιοσδήποτε μπορεί να βρει και να συμμετάσχει" "Οποιοσδήποτε" "Τα άτομα μπορούν να συμμετάσχουν μόνο εάν έχουν προσκληθεί" "Μόνο πρόσκληση" "Πρόσβαση στην αίθουσα" - "Οι χώροι δεν υποστηρίζονται προς το παρόν" "Μέλη χώρου" - "Θα χρειαστείτε μια διεύθυνση αίθουσας για να την κάνετε ορατή στον κατάλογο αιθουσών." + "Οι χώροι δεν υποστηρίζονται προς το παρόν" + "Θα χρειαστείτε μια διεύθυνση αίθουσας για να την κάνετε ορατή στον κατάλογο." "Επιστρέψτε την εύρεση αυτής της αίθουσας με αναζήτηση στον κατάλογο %1$s δημοσίων αιθουσών" "Ορατή στον κατάλογο δημόσιων αιθουσών" + "Οποιοσδήποτε" "Ποιος μπορεί να διαβάσει το ιστορικό" "Μόνο μέλη από τη στιγμή που προσκλήθηκαν" "Μόνο για μέλη μετά από αυτήν την επιλογή" "Οι διευθύνσεις αιθουσών είναι τρόποι εύρεσης και πρόσβασης σε αίθουσες. Αυτό διασφαλίζει επίσης ότι μπορείτε εύκολα να μοιραστείτε την αίθουσα με άλλους. Μπορείτε να επιλέξετε να δημοσιεύσετε την αίθουσά σας στον δημόσιο κατάλογο αιθουσών του αρχικού διακομιστή σας." "Δημοσίευση αίθουσας" - "Οι διευθύνσεις αιθουσών είναι τρόποι εύρεσης και πρόσβασης σε αίθουσες. Αυτό εξασφαλίζει επίσης ότι μπορείτε εύκολα να μοιραστείτε την αίθουσα με άλλους. -Η διεύθυνση απαιτείται επίσης για να γίνει η αίθουσα ορατή στον δημόσιο κατάλογο αιθουσών %1$s." "Ασφάλεια & απόρρητο" - "Αίτημα συμμετοχής" - "Κρυπτογράφηση" - "Οποιοσδήποτε" - "Ορατότητα αίθουσας" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-es/translations.xml b/features/securityandprivacy/impl/src/main/res/values-es/translations.xml index 912ab9db68..2799d9d196 100644 --- a/features/securityandprivacy/impl/src/main/res/values-es/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-es/translations.xml @@ -4,33 +4,31 @@ "Dirección de la sala" "Agregar dirección de sala" "Cualquiera puede solicitar unirse a la sala, pero un administrador o moderador tendrá que aceptar la solicitud." + "Solicitud para unirse" "Sí, activar cifrado" "Una vez activado, el cifrado de una sala no se puede desactivar. El historial de mensajes solo será visible para los miembros de la sala desde que fueron invitados o desde que se unieron a la sala. Nadie más que los miembros de la sala podrán leer los mensajes. Esto puede impedir que los bots y los puentes funcionen correctamente. No recomendamos habilitar el cifrado para las salas que cualquiera pueda encontrar y unirse." "¿Activar cifrado?" "Una vez activado, el cifrado no se puede desactivar." + "Cifrado" "Activar el cifrado de extremo a extremo" "Cualquiera puede encontrarla y unirse" + "Cualquiera" "Las personas solo pueden unirse si están invitadas" "Solo por invitación" "Acceso a la sala" - "No se admiten los espacios por el momento." "Miembros del espacio" - "Necesitarás una dirección de sala para que esta sea visible en el directorio de salas." + "No se admiten los espacios por el momento." + "Necesitarás una dirección de sala para que sea visible en el directorio." "Permite encontrar esta sala buscando en el directorio de salas públicas de %1$s" "Visible en el directorio de salas públicas" + "Cualquiera" "Quién puede leer el historial" "Solo participantes desde que fueron invitados" "Solo participantes desde que se selecciona esta opción" "Las direcciones de sala son formas de buscar salas y acceder a ellas. Esto también garantiza que puedas compartir fácilmente tu sala con otras personas. Puedes optar por publicar tu sala en el directorio de salas públicas de tu servidor base." "Publicación de la sala" - "Las direcciones de sala son un medio para buscar y acceder a salas. También te permiten compartir fácilmente tu sala con otras personas. -La dirección también es necesaria para hacer visible la sala en el directorio de salas públicas de %1$s." "Seguridad y privacidad" - "Solicitud para unirse" - "Cifrado" - "Cualquiera" - "Visibilidad de la sala" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-et/translations.xml b/features/securityandprivacy/impl/src/main/res/values-et/translations.xml index 77dd390f52..7e6cdec9c6 100644 --- a/features/securityandprivacy/impl/src/main/res/values-et/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-et/translations.xml @@ -2,39 +2,36 @@ "Selleks, et jututuba oleks nähtav jututubade avalikus kataloogis, vajab ta aadressi." "Muuda aadressi" - "Lisa jututoa aadress" - "Kõik võivad paluda jututoaga liitumist, kuid peakasutaja peab sellega nõustuma." + "Lisa aadress" + "Kõik võivad paluda jututoaga liitumist." + "Küsi võimalust liitumiseks" "Jah, lülita krüptimine sisse" "Kui jututoa krüptimine on kord sisse lülitatud, siis seda välja lülitada ei saa. Sõnumite ajalugu on nähtav vaid jututoa liikmetele alates kutse saamise või liitumise hetkest. Keegi teine peale jututoa liikmete ei saa sõnumeid lugeda. See võib takistada suhtlusrobotite ja/või võrgusildade toimimist. Me ei soovita krüptimise kasutamist selliste avalike jututubade puhul, millega kõik võivad liituda." "Kas võtame krüptimise kasutusele?" "Kui krüptimine on kasutusel, siis seda enam väljalülitada ei saa." + "Krüptimine" "Võta läbiv krüptimine kasutusele" "Kõik võivad jututoaga liituda" - "Avalik" + "Kõik" "Liituda saab vaid kutse olemasolul" - "Privaatne" + "Vaid kutsega" "Ligipääs" - "Kogukondade tugi veel puudub" "Kogukonna liikmed" - "Et jututuba oleks nähtav avalikus kataloogis, peab tal olema aadress." - "Selleks, et jututuba oleks nähtav jututubade kataloogis, vajab ta aadressi." - "Avaldatud aadress" + "Kogukondade tugi veel puudub" + "Selleks, et jututuba oleks nähtav jututubade avalikus kataloogis, vajab ta aadressi." + "Aadress" "Võimalda leida seda jututuba avalikust kataloogist otsides „%1$s“" "Luba leitavus avaliku kataloogi otsingust." "Nähtav avalikus kataloogis" + "Kõik" "Kes võivad lugeda jututoa ajalugu" "Liikmed peale kutse saamist" "Liikmed peale selle valiku sisselülitamist" "Jututoa aadressid annavad võimaluse neid leida ning saada neile ligi. Samuti võimaldab see jututuba teistele huvilistele jagada. Lisaks võid sa jututoa avaldada oma koduserveri avalikus jututubade kataloogis." "Jututoa avaldamine" - "Jututoa aadressid annavad võimaluse neid leida ning saada neile ligi. Samuti võimaldab see jututuba teistele huvilistele jagada. -Lisaks on aadress vajalik, et jututuba oleks %1$s serveri avalikus jututubade kataloogis nähtav." + "Nähtavus" "Turvalisus ja privaatsus" - "Küsi võimalust liitumiseks" - "Krüptimine" - "Kõik" - "Jututoa nähtavus" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-eu/translations.xml b/features/securityandprivacy/impl/src/main/res/values-eu/translations.xml index d7758c1f81..c66b6769ce 100644 --- a/features/securityandprivacy/impl/src/main/res/values-eu/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-eu/translations.xml @@ -3,20 +3,20 @@ "Gelaren helbidea" "Gehitu gelaren helbidea" "Bai, gaitu zifratzea" + "Zifratzea" "Edonork aurkitu eta bat egin dezake" + "Edonork" "Gonbidatutako pertsonak bakarrik sartu ahal izango dira" "Gonbidapen bidez" "Gelarako sarbidea" - "Gaur-gaurkoz ez da guneekin bateragarria" "Guneko kideak" - "Gelarako helbideren bat beharko duzu gelen direktorioan ikusgai egon dadila nahi baduzu." + "Gaur-gaurkoz ez da guneekin bateragarria" "Gelaren helbidea" "Gela publikoen direktorioan ikusgai" + "Edonork" "Nork irakur dezake historia" "Kideek bakarrik, gonbidatu zituztenetik" "Kideek bakarrik, aukera hau hautatu zenetik" - "Segurtasuna eta pribatutasuna" - "Zifratzea" - "Edonork" "Gelaren ikusgarritasuna" - \ No newline at end of file + "Segurtasuna eta pribatutasuna" + diff --git a/features/securityandprivacy/impl/src/main/res/values-fa/translations.xml b/features/securityandprivacy/impl/src/main/res/values-fa/translations.xml index d3e96712de..8cfa4147b5 100644 --- a/features/securityandprivacy/impl/src/main/res/values-fa/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-fa/translations.xml @@ -2,21 +2,21 @@ "نشانی اتاق" "افزودن نشانی اتاق" + "درخواست دعوت" "بله. به کار انداختن رمزنگاری" "رمزگذاری فعال شود؟" "پس از به کار افتادن، رمزنگاری قابل از کار انداختن نیست." + "رمزنگاری" "هرکسی می‌تواند یافته و بپیوندد" "هرکسی" "افراد فقط در صورت دعوت می‌توانند بپیوندند" "فقط دعوتی" "دسترسی اتاق" - "در حال حاضر فضاها پشتیبانی نمی‌شوند" "اعضای فضا" + "در حال حاضر فضاها پشتیبانی نمی‌شوند" "نشانی اتاق" - "انتشار اتاق" - "امنیت و محرمانگی" - "درخواست دعوت" - "رمزنگاری" "هرکسی" + "انتشار اتاق" "نمایانی اتاق" - \ No newline at end of file + "امنیت و محرمانگی" + diff --git a/features/securityandprivacy/impl/src/main/res/values-fi/translations.xml b/features/securityandprivacy/impl/src/main/res/values-fi/translations.xml index 87440b626a..0f42d87675 100644 --- a/features/securityandprivacy/impl/src/main/res/values-fi/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-fi/translations.xml @@ -1,38 +1,37 @@ - "Tarvitset huoneen osoitteen, jotta se näkyy hakemistossa." - "Huoneen osoite" - "Lisää huoneen osoite" - "Kuka tahansa voi pyytää saada liittyä huoneeseen, mutta ylläpitäjän tai valvojan on hyväksyttävä pyyntö." + "Tarvitset osoitteen, jotta se näkyy julkisessa hakemistossa." + "Muokkaa osoitetta" + "Lisää osoite" + "Kaikkien on pyydettävä pääsyä." + "Pyydä liittymistä" "Kyllä, ota salaus käyttöön" "Kun salaus on kerran otettu käyttöön, sitä ei voi poistaa käytöstä. Viestihistoria näkyy vain huoneen jäsenille kutsusta tai liittymisestä lähtien. Kukaan muu kuin huoneen jäsenet eivät pysty lukemaan viestejä. Tämä voi estää botteja tai siltoja toimimasta oikein. Emme suosittele salauksen ottamista käyttöön huoneissa, jotka kuka tahansa voi löytää ja joihin kuka tahansa voi liittyä." "Otetaanko salaus käyttöön?" "Kun salaus on kerran otettu käyttöön, sitä ei voi poistaa käytöstä." + "Salaus" "Ota päästä päähän -salaus käyttöön" - "Kuka tahansa voi löytää ja liittyä." + "Kuka tahansa voi liittyä." "Kuka tahansa" - "Vain kutsutut henkilöt voivat liittyä" + "Vain kutsutut henkilöt voivat liittyä." "Vain kutsutut" - "Huoneeseen pääsy" - "Tiloja ei tällä hetkellä tueta" + "Pääsy" "Tilan jäsenet" - "Tarvitset huoneen osoitteen, jotta se näkyy huonehakemistossa." - "Huoneen osoite" + "Tiloja ei tällä hetkellä tueta" + "Tarvitset osoitteen, jotta se näkyy julkisessa hakemistossa." + "Osoite" "Salli tämän huoneen löytäminen hakemalla %1$s -palvelimen julkisesta huonehakemistosta." - "Näkyy julkisessa huonehakemistossa" + "Anna muiden löytää tämä julkisen hakemiston kautta." + "Näkyy julkisessa hakemistossa" + "Kuka tahansa" "Kuka voi lukea viestihistoriaa" "Jäsenet vasta kutsusta lähtien" "Jäsenet tämän vaihtoehdon valinnan jälkeen" "Huoneosoitteet ovat tapoja löytää ja käyttää huoneita. Näin voit myös helposti jakaa huoneesi muiden kanssa. Voit halutessasi julkaista huoneesi kotipalvelimesi julkisessa huonehakemistossa." "Huoneen julkaiseminen" - "Huoneosoitteet ovat tapoja löytää ja käyttää huoneita. Näin voit myös helposti jakaa huoneesi muiden kanssa. -Osoitetta tarvitaan myös, jotta huone näkyy %1$s -palvelimen julkisessa huonehakemistossa." + "Näkyvyys" "Turvallisuus ja yksityisyys" - "Pyydä liittymistä" - "Salaus" - "Kuka tahansa" - "Huoneen näkyvyys" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml b/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml index 7a4be5d37a..754ef4cd1a 100644 --- a/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-fr/translations.xml @@ -1,38 +1,38 @@ - "Vous aurez besoin d\'une adresse de salon pour le rendre visible dans le répertoire." - "Adresse du salon" - "Ajouter l\'adresse du salon" - "N\'importe qui peut demander à rejoindre le salon, mais un administrateur ou un modérateur devra accepter la demande." + "Vous aurez besoin d’une adresse pour le rendre visible dans l’annuaire public." + "Modifier l’adresse" + "Ajouter une adresse" + "Tout le monde doit demander un accès." + "Demander à rejoindre" "Oui, activer le chiffrement" - "Une fois activé, le chiffrement d\'un salon ne peut pas être désactivé. L\'historique des messages ne sera visible que pour les membres depuis qu\'ils ont été invités ou depuis qu\'ils ont rejoint le salon. -Personne d\'autre que les membres du salon ne pourra lire les messages. Cela peut empêcher les bots et les bridges de fonctionner correctement. -Nous ne recommandons pas d\'activer le chiffrement pour les salons que tout le monde peut trouver et rejoindre." + "Une fois activé, le chiffrement d’un salon ne peut pas être désactivé. L’historique des messages ne sera visible que pour les membres depuis qu’ils ont été invités ou depuis qu’ils ont rejoint le salon. +Personne d’autre que les membres du salon ne pourra lire les messages. Cela peut empêcher les bots et les bridges de fonctionner correctement. +Nous ne recommandons pas d’activer le chiffrement pour les salons que tout le monde peut trouver et rejoindre." "Activer le chiffrement ?" "Une fois activé, le chiffrement ne peut pas être désactivé." - "Activer le chiffrement de bout en bout" - "Tout le monde peut le trouver et le rejoindre" - "Tout le monde" - "Le salon ne peut être joint que par les personnes invitées" - "Sur invitation uniquement" - "Accès au salon" - "Les Espaces ne sont pas encore supportés" - "Membres de l\'espace" - "Vous aurez besoin de l\'adresse du salon pour le rendre visible dans le répertoire des salons." - "Adresse du salon" - "Autoriser le salon à apparaître dans les résultats de recherche dans le répertoire %1$s des salons publics" - "Visible dans le répertoire des salons publics" - "Qui peux lire l\'historique" - "Les membres uniquement depuis qu\'ils ont été invités" - "Les membres uniquement depuis la sélection de cette option" - "Les adresses de salon sont un moyen de trouver et d\'accéder aux salons. Cela vous permet également de partager facilement votre salon avec d\'autres personnes. -Vous pouvez choisir de publier votre salon dans l\'annuaire des salons publics de votre serveur d’accueil." - "Publication du salon" - "Les adresses de salon sont un moyen de trouver et d\'accéder aux salons. Cela vous permet également de partager facilement votre salon avec d\'autres personnes. -L\'adresse est également requise pour que le salon soit visible dans le répertoire %1$s des salons publics." - "Sécurité & confidentialité" - "Demander à rejoindre" "Chiffrement" + "Activer le chiffrement de bout en bout" + "Tout le monde peut rejoindre." + "Tout le monde" + "Seules les personnes invitées peuvent rejoindre." + "Sur invitation uniquement" + "Accès" + "Membres de l’espace" + "Les Espaces ne sont pas encore supportés" + "Vous aurez besoin d’une adresse pour le rendre visible dans l’annuaire public." + "Adresse" + "Autoriser le salon à apparaître dans les résultats de recherche dans le répertoire %1$s des salons publics" + "Permet d’être trouvé en recherchant dans l’annuaire public." + "Visible dans l’annuaire public" "Tout le monde" - "Visibilité du salon" - \ No newline at end of file + "Qui peux lire l’historique" + "Les membres uniquement depuis qu’ils ont été invités" + "Les membres uniquement depuis la sélection de cette option" + "Les adresses de salon sont un moyen de trouver et d’accéder aux salons. Cela vous permet également de partager facilement votre salon avec d’autres personnes. +Vous pouvez choisir de publier votre salon dans l’annuaire des salons publics de votre serveur d’accueil." + "Publication du salon" + "Les adresses permettent de trouver et d’accéder aux salons et aux espaces. Elles facilitent également leur partage avec d’autres personnes." + "Visibilité" + "Sécurité & confidentialité" + diff --git a/features/securityandprivacy/impl/src/main/res/values-hu/translations.xml b/features/securityandprivacy/impl/src/main/res/values-hu/translations.xml index b32923dba6..503fdc8efe 100644 --- a/features/securityandprivacy/impl/src/main/res/values-hu/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-hu/translations.xml @@ -2,39 +2,36 @@ "Szüksége lesz egy szobacímre, hogy láthatóvá tegye a szobakatalógusban." "Cím szerkesztése" - "Szobacím hozzáadása" - "Bárki kérhet hozzáférést, de a kérést egy adminisztrátornak kell jóváhagynia." + "Cím hozzáadása" + "Mindenkinek hozzáférést kell kérnie." + "Csatlakozás kérése" "Igen, engedélyezze a titkosítást" "Az engedélyezés után a szoba titkosítása nem tiltható le. Az üzenetek előzményei csak a szobatagok számára láthatók, amikor meghívást kaptak, vagy mióta csatlakoztak a szobához. A szobatagokon kívül senki sem tudja olvasni az üzeneteket. Ez megakadályozhatja a botok és a hidak megfelelő működését. Nem javasoljuk a titkosítás engedélyezését az olyan szobákban, amelyeket bárki megtalálhat és csatlakozhat." "Engedélyezi a titkosítást?" "Engedélyezés után a titkosítás nem tiltható le." + "Titkosítás" "Végpontok közötti titkosítás engedélyezése" "Bárki csatlakozhat." - "Nyilvános" + "Bárki" "Csak a meghívott emberek léphetnek be." - "Privát" + "Csak meghívásos" "Hozzáférés" - "A terek jelenleg nem támogatottak" "A tér tagjai" - "Szüksége lesz egy szobacímre, hogy láthatóvá tegye a szobakatalógusban." - "Szüksége lesz egy szobacímre, hogy láthatóvá váljon a szobakatalógusban." - "Közzétett cím" + "A terek jelenleg nem támogatottak" + "Szüksége lesz egy szobacímre, hogy láthatóvá tegye a szobakatalógusban." + "Cím" "A szoba megtalálhatóvá tétele a(z) %1$s nyilvános szobakatalógusában való kereséssel." "Lehetővé teszi, hogy a nyilvános szobakatalógusban megtalálható legyen." "Látható a nyilvános szobakatalógusban" + "Bárki" "Ki olvashatja az előzményeket" "Csak a tagok, a meghívásuktól kezdődően" "Csak a tagok, a beállítás választásától kezdődően" "A szobacímek a szobák megtalálásának és elérésnek módjai. Ez azt is biztosítja, hogy könnyen megoszthatja a szobáját másokkal. Kiválaszthatja, hogy szobáját közzéteszi-e a Matrix-kiszolgáló nyilvános szobakatalógusában." "Szoba közzététele" - "A szobacímek a szobák megtalálásának és elérésnek módjai. Ez azt is biztosítja, hogy könnyen megoszthatja a szobáját másokkal. -A cím szükséges ahhoz is, hogy a nyilvános szoba láthatóvá váljon a(z) %1$s kiszolgáló nyilvános szobakatalógusában." + "Láthatóság" "Biztonság és adatvédelem" - "Csatlakozás kérése" - "Titkosítás" - "Bárki" - "Szoba láthatósága" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-in/translations.xml b/features/securityandprivacy/impl/src/main/res/values-in/translations.xml index 836ad66302..17f14057cb 100644 --- a/features/securityandprivacy/impl/src/main/res/values-in/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-in/translations.xml @@ -4,32 +4,30 @@ "Alamat ruangan" "Tambahkan alamat ruangan" "Siapa pun dapat meminta untuk bergabung dengan ruangan tetapi administrator atau moderator harus menerima permintaan tersebut." + "Minta untuk bergabung" "Ya, aktifkan enkripsi" "Setelah diaktifkan, encryption untuk sebuah ruangan tidak dapat dinonaktifkan, Riwayat pesan hanya akan terlihat oleh anggota ruangan sejak mereka diundang atau sejak mereka bergabung dengan ruangan tersebut. Tidak ada orang lain selain anggota ruangan yang dapat membaca pesan. Hal ini dapat mencegah bot dan jembatan bekerja dengan benar. Kami tidak menyarankan untuk mengaktifkan enkripsi untuk ruangan yang dapat ditemukan dan diikuti oleh siapa pun." "Aktifkan enkripsi?" "Setelah diaktifkan, enkripsi tidak dapat dinonaktifkan." + "Enkripsi" "Aktifkan enkripsi ujung ke ujung" "Siapa pun dapat menemukan dan bergabung" + "Siapa pun" "Orang hanya dapat bergabung jika mereka diundang" "Hanya undangan" "Akses ruangan" - "Space saat ini tidak didukung" "Anggota space" - "Anda memerlukan alamat ruangan agar dapat membuatnya terlihat di direktori ruangan." + "Space saat ini tidak didukung" + "Anda akan memerlukan alamat ruangan untuk membuatnya terlihat dalam direktori." "Izinkan ruangan ini ditemukan dengan mencari direktori ruangan %1$s publik" "Terlihat di direktori ruangan publik" + "Siapa pun" "Siapa yang bisa membaca riwayat" "Hanya anggota sejak mereka diundang" "Hanya anggota sejak memilih opsi ini" "Alamat ruangan adalah cara untuk menemukan dan mengakses ruangan. Ini juga memastikan Anda dapat dengan mudah berbagi ruangan dengan orang lain. Anda dapat memilih untuk menerbitkan ruangan Anda di direktori ruangan publik homeserver Anda." "Penerbitan ruangan" - "Alamat ruangan adalah cara untuk menemukan dan mengakses ruangan. Hal ini juga memastikan Anda dapat dengan mudah berbagi ruangan dengan orang lain. -Alamat ini juga diperlukan untuk membuat ruangan terlihat di %1$s direktori ruangan publik." "Keamanan & privasi" - "Minta untuk bergabung" - "Enkripsi" - "Siapa pun" - "Keterlihatan ruangan" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-it/translations.xml b/features/securityandprivacy/impl/src/main/res/values-it/translations.xml index 2148691b24..2854a69ce1 100644 --- a/features/securityandprivacy/impl/src/main/res/values-it/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-it/translations.xml @@ -1,37 +1,38 @@ - "Avrai bisogno di un indirizzo della stanza per renderla visibile nell\'elenco." - "Indirizzo della stanza" - "Aggiungi l\'indirizzo della stanza" - "Chiunque può chiedere di entrare nella stanza, ma un amministratore o un moderatore dovrà accettare la richiesta." + "Per renderlo visibile nell\'elenco pubblico, avrai bisogno di un indirizzo." + "Modifica indirizzo" + "Aggiungi indirizzo" + "Chiunque deve richiedere l\'accesso." + "Chiedi di entrare" "Sì, attiva la crittografia" "Una volta attivata, la crittografia di una stanza non può essere disattivata, la cronologia dei messaggi sarà visibile solo ai membri della stanza da quando sono stati invitati o da quando sono entrati nella stanza. Nessuno, oltre ai membri della stanza, sarà in grado di leggere i messaggi. Ciò potrebbe impedire ai bot e ai bridge di funzionare correttamente. Non consigliamo di attivare la crittografia per le stanze che chiunque può trovare e in cui può entrare." "Attivare la crittografia?" "Una volta attivata, la crittografia non può essere disattivata." + "Crittografia" "Attiva la crittografia end-to-end" - "Chiunque può trovare ed entrare" + "Chiunque può partecipare." "Chiunque" - "Le persone possono partecipare solo se invitate" + "Solo le persone invitate possono entrare." "Solo su invito" - "Accesso alla stanza" - "Gli spazi non sono attualmente supportati" + "Accesso" "Membri dello spazio" - "Per rendere visibile la stanza nell\'elenco delle stanze, è necessario l\'indirizzo della stanza." - "Indirizzo della stanza" + "Gli spazi non sono attualmente supportati" + "Per renderlo visibile nell\'elenco pubblico, avrai bisogno di un indirizzo." + "Indirizzo" "Consenti la ricerca di questa stanza effettuando una ricerca nell\'elenco delle stanze pubbliche di %1$s" - "Visibile nell\'elenco delle stanze pubbliche" + "Consenti di essere trovato effettuando una ricerca nell\'elenco pubblico." + "Visibile nell\'elenco pubblico" + "Chiunque" "Chi può leggere la cronologia messaggi" "Solo membri da quando sono stati invitati" "Solo membri da dopo aver selezionato questa opzione" "Gli indirizzi delle stanze sono modi per trovare e accedervi. In questo modo puoi anche condividere facilmente la tua stanze con altri. Puoi scegliere di pubblicare la tua stanza nell\'elenco delle stanza pubbliche dell\'homeserver." "Pubblicazione della stanza" - "Gli indirizzi delle stanze sono modi per trovare e accedere a queste ultime. Questo assicura anche che tu possa condividere facilmente la tua stanza con altri. L\'indirizzo è anche necessario per rendere la stanza visibile in %1$s nell\'elenco delle stanze pubbliche." + "Gli indirizzi sono un modo per trovare e accedere a stanze e spazi. Questo ti consente anche di condividerli facilmente con altri." + "Visibilità" "Sicurezza e privacy" - "Chiedi di entrare" - "Crittografia" - "Chiunque" - "Visibilità della stanza" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-ko/translations.xml b/features/securityandprivacy/impl/src/main/res/values-ko/translations.xml index b144b6bdde..8afa1987eb 100644 --- a/features/securityandprivacy/impl/src/main/res/values-ko/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-ko/translations.xml @@ -4,33 +4,31 @@ "방 주소" "방 주소 추가" "누구나 방에 참여 요청을 할 수 있지만, 관리자나 운영자가 요청을 수락해야 합니다." + "참가 요청" "예, 암호화 활성화" "일단 활성화되면, 방의 암호화는 비활성화할 수 없습니다. 메시지 기록은 방에 초대된 후 또는 방에 참여한 이후부터 방 구성원만 볼 수 있습니다. 방 구성원 외에는 아무도 메시지를 읽을 수 없습니다. 이로 인해 봇과 브리지가 제대로 작동하지 않을 수 있습니다. 누구나 찾고 참여할 수 있는 방에는 암호화를 활성화하지 않는 것이 좋습니다." "암호화 활성화?" "일단 활성화되면, 암호화는 비활성화할 수 없습니다." + "암호화" "종단간 암호화 활성화" "누구나 찾을 수 있고 참여할 수 있습니다." + "누구나" "초대받은 사용자만 가입할 수 있습니다." "초대 전용" "방 액세스" - "스페이스는 현재 지원되지 않습니다" "스페이스 멤버들" - "방 디렉토리에 표시하려면 방 주소가 필요합니다." + "스페이스는 현재 지원되지 않습니다" + "디렉토리에 표시하려면 방 주소가 필요합니다." "%1$s 공개 방 디렉토리에서 이 방을 검색할 수 있도록 허용합니다" "공개 룸 디렉토리에 표시됨" + "누구나" "누가 기록을 읽을 수 있는가" "초대받은 회원만 이용 가능합니다" "이 옵션을 선택한 회원만 이용 가능합니다." "방 주소는 방을 찾고 액세스하는 방법입니다. 이를 통해 다른 사람들과 방을 쉽게 공유할 수 있습니다. 홈서버의 공개 방 디렉토리에 방을 공개할지 여부를 선택할 수 있습니다." "방 게시" - "방 주소는 방을 찾고 액세스하는 방법입니다. 또한 이 주소를 사용하면 다른 사람들과 방을 쉽게 공유할 수 있습니다. -%1$s 의 공개 방 디렉토리에서 방을 표시하려면 이 주소도 필요합니다." "보안 및 개인정보 보호" - "참가 요청" - "암호화" - "누구나" - "방 표시 여부" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-nb/translations.xml b/features/securityandprivacy/impl/src/main/res/values-nb/translations.xml index 02f2163c51..2d0f8db8a5 100644 --- a/features/securityandprivacy/impl/src/main/res/values-nb/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-nb/translations.xml @@ -4,33 +4,31 @@ "Romadresse" "Legg til romadresse" "Alle kan be om å bli med i rommet, men en administrator eller moderator må godta forespørselen." + "Be om å bli med" "Ja, aktiver kryptering" "Når kryptering for et rom er aktivert, kan den ikke deaktiveres. Meldingshistorikken vil bare være synlig for rommedlemmer siden de ble invitert eller siden de ble med i rommet. Ingen andre enn rommedlemmene vil kunne lese meldingene. Dette kan føre til at bots og broer ikke fungerer som de skal. Vi anbefaler ikke å aktivere kryptering for rom som hvem som helst kan finne og bli med i." "Vil du aktivere kryptering?" "Når kryptering er aktivert, kan det ikke deaktiveres." + "Kryptering" "Aktiver ende-til-ende-kryptering" "Alle kan finne og bli med" + "Alle" "Folk kan bare bli med hvis de er invitert" "Kun for inviterte" "Tilgang til rom" - "Områder støttes ikke for øyeblikket" "Medlemmer av område" - "Du trenger en adresse til rommet for å gjøre rommet synlig i romkatalogen." + "Områder støttes ikke for øyeblikket" + "Du trenger en adresse til rommet for å gjøre det synlig i katalogen." "Tillat at dette rommet blir funnet ved å søke %1$s offentlig romkatalog" "Synlig i offentlig romkatalog" + "Alle" "Hvem kan lese historikk" "Medlemmer bare siden de ble invitert" "Kun medlemmer siden du valgte dette alternativet" "Romadresser er måter å finne og få tilgang til rom på. Dette sikrer også at du enkelt kan dele rommet ditt med andre. Du kan velge å publisere rommet ditt i hjemeserverens offentlige romkatalog." "Publisering av rom" - "Romadresser er en måte å finne og få tilgang til rommene på. Dette sikrer også at du enkelt kan dele rommet ditt med andre. -Adressen er også nødvendig for å gjøre rommet synlig i den offentlige romkatalogen på %1$s." "Sikkerhet og personvern" - "Be om å bli med" - "Kryptering" - "Alle" - "Romsynlighet" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-nl/translations.xml b/features/securityandprivacy/impl/src/main/res/values-nl/translations.xml index 3913599edb..5fdc9466b5 100644 --- a/features/securityandprivacy/impl/src/main/res/values-nl/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-nl/translations.xml @@ -1,5 +1,6 @@ "Vraag om toe te treden" + "Iedereen" "Iedereen" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-pl/translations.xml b/features/securityandprivacy/impl/src/main/res/values-pl/translations.xml index 8cad565318..11b8189cc4 100644 --- a/features/securityandprivacy/impl/src/main/res/values-pl/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-pl/translations.xml @@ -4,35 +4,33 @@ "Adres pokoju" "Dodaj adres pokoju" "Każdy może poprosić o dołączenie do pokoju, ale administrator lub moderator będzie musiał zatwierdzić żądanie." + "Poproś o dołączenie" "Tak, włącz szyfrowanie" "Po włączeniu szyfrowanie pokoju nie może zostać wyłączone, a historia wiadomości będzie widoczna tylko dla członków od momentu, w którym dołączyli lub zostali zaproszeni. Nikt poza członkami pokoju nie będzie mógł czytać wiadomości. Może to wpłynąć na prawidłowe działanie botów lub mostków. Odradzamy włączanie szyfrowania dla pokoi, które każdy może znaleźć i do których każdy może dołączyć." "Włączyć szyfrowanie?" "Po włączeniu szyfrowania nie można wyłączyć." + "Szyfrowanie" "Włącz szyfrowanie end-to-end" "Każdy może znaleźć i dołączyć" - "Każdy" + "Wszyscy" "Tylko osoby z zaproszeniem mogą dołączyć" "Tylko zaproszenie" "Dostęp do pokoju" - "Przestrzenie nie są obecnie wspierane" "Członkowie przestrzeni" - "Aby pokój był widoczny w katalogu pokoi, potrzebny jest adres pokoju." + "Przestrzenie nie są obecnie wspierane" + "Aby pokój był widoczny w katalogu, potrzebny jest adres pokoju." "Adres pokoju" "Zezwól na znalezienie tego pokoju wyszukując %1$s w katalogu pokoi publicznych" "Widoczny w katalogu pokoi publicznych" + "Wszyscy" "Kto może czytać historię" "Od momentu kiedy członkowie zostali zaproszeni" "Członkowie od momentu włączenia tej opcji" "Adresy pokoju umożliwiają łatwe znalezienie i dołączenie do pokojów. Również możesz się zdecydować na upublicznienie Twojego serwera w katalogu pokoi publicznych." "Publikowanie pokoju" - "Adresy pokoju umożliwiają łatwe znalezienie i dołączenie do pokojów. -Dodatkowo adres pokoju jest wymagany, aby pomieszczenie było widoczne w katalogu pokoi publicznych %1$s." + "Widoczność pokoju" "Bezpieczeństwo i prywatność" - "Poproś o dołączenie" - "Szyfrowanie" - "Wszyscy" - "Widoczność pomieszczenia" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml b/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml index 980fb118fb..584e94dc20 100644 --- a/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-pt-rBR/translations.xml @@ -1,36 +1,38 @@ - "Você precisará de um endereço de sala para torná-la visível no diretório." - "Endereço da sala" - "Adicionar endereço da sala" - "Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou moderador terá que aceitar o pedido." + "Você precisará de um endereço para torná-la visível no diretório." + "Editar endereço" + "Adicionar endereço" + "Qualquer um pode pedir acesso, mas um administrador terá que aceitar o pedido." + "Pedir para entrar" "Sim, ativar a criptografia" "Uma vez ativada, a criptografia de uma sala não pode ser desativada. O histórico de mensagens só será visível para os membros da sala desde que foram convidados ou desde que entraram na sala. Ninguém além dos membros da sala poderá ler as mensagens. Isso pode impedir que os bots e as pontes funcionem corretamente. Não recomendamos que você ative a criptografia para salas que qualquer pessoa possa encontrar e participar." "Ativar a criptografia?" "Uma vez ativada, a criptografia não poderá ser desativada." + "Criptografia" "Ativar a criptografia de ponta a ponta" - "Qualquer um pode encontrar e entrar" - "As pessoas só podem participar se forem convidadas" - "Somente para convidados" - "Acesso à sala" - "No momento, não há suporte aos espaços" + "Qualquer um pode entrar" + "Qualquer pessoa" + "Apenas pessoas convidadas podem entrar." + "Privado" + "Acesso" "Membros do espaço" - "Você precisará de um endereço de sala para torná-la visível no diretório de salas." + "No momento, não há suporte aos espaços" + "Você precisará de um endereço para torná-la visível no diretório." + "Endereço publicado" "Permitir que esta sala seja encontrada pesquisando diretório de salas públicas de %1$s" - "Visível no diretório de salas públicas" + "Permite que seja encontrada ao buscar no diretório público." + "Visível no diretório público" + "Qualquer pessoa" "Quem pode ler o histórico" "Somente membros, desde que foram convidados" "Somente para membros após selecionar esta opção" "Os endereços das salas são formas de encontrar e acessar as salas. Isso também garante que você possa compartilhar facilmente sua sala com outras pessoas. Você pode optar por publicar sua sala no diretório público de salas do seu servidor-casa." "Publicação da sala" - "Os endereços das salas são formas de encontrar e acessar as salas. Isso também garante que você possa compartilhar facilmente sua sala com outras pessoas. -O endereço também é necessário para que você possa ver a sala no diretório público de salas do %1$s." + "Os endereços das salas são formas de encontrar e acessar as salas. Isso também garante que você possa compartilhá-las facilmente com outras pessoas." + "Visibilidade" "Segurança e privacidade" - "Pedir para entrar" - "Criptografia" - "Qualquer pessoa" - "Visibilidade da sala" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-pt/translations.xml b/features/securityandprivacy/impl/src/main/res/values-pt/translations.xml index cdf157ab11..26585dc4f9 100644 --- a/features/securityandprivacy/impl/src/main/res/values-pt/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-pt/translations.xml @@ -4,35 +4,33 @@ "Endereço da sala" "Adicionar endereço de sala" "Qualquer pessoa pode pedir para entrar na sala, mas um administrador ou moderador tem que aceitar o pedido." + "Pedir para participar" "Sim, ativar cifragem" "Uma vez ativada, a cifragem não pode ser desativada. O histórico de mensagens só será visível a membros a partir do momento em que foram convidados ou que entraram na sala. Ninguém além dos membros poderão ler quaisquer mensagens. Isto pode impedir que robôs (\"bots\") e pontes (\"bridges\") funcionem devidamente. Não recomendamos ativar a cifragem em salas que qualquer pessoa possa encontrar e entrar." "Ativar cifragem?" "Uma vez ativada, a cifragem não pode ser desativada." + "Cifragem" "Ativar cifragem ponta-a-ponta" "Qualquer pessoa pode encontrar a sala e entrar" "Qualquer pessoa" "Só é possível entrar tendo um convite" "Apenas por convite" "Acesso à sala" - "Os espaços ainda não estão implementados" "Membros do espaço" + "Os espaços ainda não estão implementados" "É necessário um endereço para tornar a sala visível no diretório." "Endereço da sala" "Permite que esta sala seja encontrada através do diretório público do %1$s." "Visível no diretório público de salas" + "Qualquer pessoa" "Quem pode ler o histórico de mensagens" "Apenas membros, desde o momento em que forem convidados" "Apenas membros, desde o memento em que esta opção for selecionada" "Estes endereços permitem encontrar e aceder a sala, bem como a sua fácil partilha com outros. Podes escolher publicar a sala no diretório público do teu servidor." "Publicar sala" - "Estes endereços permitem encontrar e aceder a sala, bem como a sua fácil partilha com outros. -Além disso, é necessário ter endereço para publicar a sala no diretório público do %1$s." - "Segurança e privacidade" - "Pedir para participar" - "Cifragem" - "Qualquer pessoa" "Visibilidade da sala" - \ No newline at end of file + "Segurança e privacidade" + diff --git a/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml b/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml index 2bd0e41582..213e35562d 100644 --- a/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-ro/translations.xml @@ -4,33 +4,31 @@ "Adresa camerei" "Adăugați adresa camerei" "Oricine poate cere să se alăture camerei, dar un administrator sau moderator va trebui să accepte cererea." + "Cereți să vă alăturați" "Da, activați criptarea" "Odată activată, criptarea pentru o cameră nu poate fi dezactivată. Mesajele anterioare vor fi vizibile numai pentru membrii camerei de la momentul la care au fost invitați sau de la momentul la care s-au alăturat camerei. Nimeni în afară de membrii camerei nu va putea citi messaje. Acest lucru poate împiedica funcționarea corectă a boților și a punților. Nu recomandăm activarea criptării pentru camerele pe care oricine le poate găsi și la care se poate alătura." "Activați criptarea?" "Odată activată, criptarea nu poate fi dezactivată." + "Criptare" "Activați criptarea end-to-end" "Oricine poate găsi și alătura camerei" + "Oricine" "Persoanele se pot alătura numai dacă invitate" "Doar pe bază de invitație" "Acces la cameră" - "Spațiile nu sunt momentan suportate." "Membrii spațiului" - "Veți avea nevoie de o adresă de cameră pentru a o face vizibilă în directorul de camere." + "Spațiile nu sunt momentan suportate." + "Veți avea nevoie de o adresă de cameră pentru a o face vizibilă în director." "Permiteți găsirea acestei camere prin căutarea în directorul de camere publice al %1$s" "Vizibilă în directorul de camere publice" + "Oricine" "Cine poate citi mesajele anterioare" "Doar pentru membri, de la momentul în care au fost invitați" "Doar pentru membri, după selectarea acestei opțiuni" "Adresele camerelor sunt modalități de a găsi și accesa camere. Acest lucru vă asigură, de asemenea, că puteți partaja cu ușurință camera dumneavoastră cu alte persoane. Puteți alege să publicați camera în directorul public al camerelor serverului dumneavoastră." "Publicare cameră" - "Adresele camerelor sunt modalități de a găsi și accesa camerele. Acest lucru vă asigură, de asemenea, că puteți partaja cu ușurință camera dvs. cu alte persoane. -Adresa este necesară și pentru ca camera să fie vizibilă în directorul public de camere al %1$s." "Securitate & confidențialitate" - "Cereți să vă alăturați" - "Criptare" - "Oricine" - "Vizibilitatea camerei" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-ru/translations.xml b/features/securityandprivacy/impl/src/main/res/values-ru/translations.xml index 1a54034ee5..1a138fbb94 100644 --- a/features/securityandprivacy/impl/src/main/res/values-ru/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-ru/translations.xml @@ -2,39 +2,36 @@ "Вам понадобится адрес комнаты, чтобы сделать ее видимой в каталоге." "Редактировать адрес комнаты" - "Добавить адрес комнаты" - "Любой желающий может подать заявку на присоединение к комнате, но администратор должен будет принять запрос." + "Добавить адрес" + "Каждый должен запросить доступ." + "Попросить присоединиться" "Да, включить шифрование" "Шифрование комнаты нельзя будет отключить, история сообщений будет видна только участникам комнаты с момента их приглашения или с момента присоединения к комнате. Никто, кроме членов комнаты, не сможет читать сообщения. Это может помешать ботам и мостам работать корректно. Мы не рекомендуем включать шифрование для комнат, в которые может найти и присоединиться любой желающий." "Включить шифрование?" "После включения, шифрование не может быть отключено." + "Шифрование" "Включить сквозное шифрование" "Любой желающий может найти и присоединиться" - "Публичный" + "Любой" "Присоединиться могут только приглашенные люди." "Только по приглашению" "Доступ" - "Пространства в настоящее время не поддерживаются." "Участники пространства" - "Вам необходимо добавить адрес комнаты, чтобы сделать ее видимой в каталоге." - "Вам понадобится адрес комнаты, чтобы сделать ее видимой в каталоге комнат." - "Опубликованный адрес" + "Пространства в настоящее время не поддерживаются." + "Вам понадобится адрес комнаты, чтобы сделать ее видимой в каталоге." + "Адрес" "Опубликовать %1$s в каталоге публичных комнат" "Разрешить поиск в публичном каталоге." "Доступна в списке публичных комнат" + "Любой" "Кто может читать историю" "Участники только с тех пор, как они были приглашены" "Только для участников с момента выбора этой опции" "Адреса комнат — это способ найти комнату и получить к ней доступ. Это также гарантирует, что вы сможете легко поделиться своей комнатой с другими. Вы можете опубликовать свою комнату в каталоге общедоступных комнат на домашнем сервере." "Публикация комнат" - "Адреса комнат — это способ найти комнату и получить к ним доступ. Это также гарантирует, что вы сможете легко поделиться своей комнатой с другими. -Адрес также необходим для отображения комнаты в каталоге %1$s общедоступных комнат." + "Видимость" "Безопасность и конфиденциальность" - "Попросить присоединиться" - "Шифрование" - "Любой" - "Видимость комнаты" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-sk/translations.xml b/features/securityandprivacy/impl/src/main/res/values-sk/translations.xml index 287fa1f442..a9e6b1dd1b 100644 --- a/features/securityandprivacy/impl/src/main/res/values-sk/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-sk/translations.xml @@ -4,35 +4,33 @@ "Adresa miestnosti" "Pridať adresu miestnosti" "Ktokoľvek môže požiadať o pripojenie do miestnosti, ale správca alebo moderátor bude musieť žiadosť prijať." + "Požiadať o pripojenie" "Áno, povoliť šifrovanie" "Po aktivácii nie je možné zakázať šifrovanie pre miestnosť. História správ bude viditeľná len pre členov miestnosti, odkedy boli pozvaní alebo keď vstúpili do miestnosti. Nikto okrem členov miestnosti nebude môcť čítať správy. To môže brániť správnemu fungovaniu robotov a premostení. Neodporúčame povoliť šifrovanie pre miestnosti, ktoré môže ktokoľvek nájsť a pripojiť sa k nim." "Povoliť šifrovanie?" "Po zapnutí už šifrovanie nie je možné vypnúť." + "Šifrovanie" "Povoliť end-to-end šifrovanie" "Ktokoľvek môže nájsť a pripojiť sa" "Ktokoľvek" "Ľudia sa môžu pripojiť len vtedy, ak sú pozvaní" "Iba na pozvánku" "Prístup do miestnosti" - "Priestory momentálne nie sú podporované" "Členovia priestoru" - "Budete potrebovať adresu miestnosti, aby bola viditeľná v adresári miestností." + "Priestory momentálne nie sú podporované" + "Budete potrebovať adresu miestnosti, aby bola viditeľná v adresári." "Adresa miestnosti" "Umožniť vyhľadanie tejto miestnosti v adresári verejných miestností %1$s" "Viditeľné v adresári verejných miestností" + "Ktokoľvek" "Kto môže čítať históriu" "Len pre členov, odkedy boli pozvaní" "Len členovia od zvolenia tejto možnosti" "Adresy miestností predstavujú spôsoby, ako nájsť a získať prístup k miestnostiam. To tiež zaisťuje, že môžete jednoducho zdieľať svoju miestnosť s ostatnými. Môžete sa rozhodnúť zverejniť svoju miestnosť v adresári verejných miestností vášho domovského servera." "Zverejnenie miestnosti" - "Adresy miestností predstavujú spôsoby, ako nájsť a získať prístup k miestnostiam. Toto tiež zaisťuje, že môžete jednoducho zdieľať svoju miestnosť s ostatnými. -Adresa je tiež potrebná, aby bola miestnosť viditeľná v adresári verejných miestností %1$s." - "Bezpečnosť a súkromie" - "Požiadať o pripojenie" - "Šifrovanie" - "Ktokoľvek" "Viditeľnosť miestnosti" - \ No newline at end of file + "Bezpečnosť a súkromie" + diff --git a/features/securityandprivacy/impl/src/main/res/values-sv/translations.xml b/features/securityandprivacy/impl/src/main/res/values-sv/translations.xml index b8d76de9bf..4fbfe47ba7 100644 --- a/features/securityandprivacy/impl/src/main/res/values-sv/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-sv/translations.xml @@ -4,34 +4,31 @@ "Rumsadress" "Lägg till rumsadress" "Vem som helst kan be om att gå med i rummet men en administratör eller moderator måste acceptera begäran." + "Be om att gå med" "Ja, aktivera kryptering" "När det är aktiverat kan kryptering för ett rum inte inaktiveras, meddelandehistoriken visas bara för rumsmedlemmar sedan de blev inbjudna eller sedan de gick med i rummet. Ingen förutom rumsmedlemmarna kommer att kunna läsa meddelanden. Detta kan förhindra att bots och bridges fungerar korrekt. Vi rekommenderar inte att aktivera kryptering för rum som vem som helst kan hitta och gå med i." "Aktivera kryptering?" "Efter aktivering kan kryptering inte inaktiveras." + "Kryptering" "Aktivera totalsträckskryptering" "Vem som helst kan hitta och gå med" "Vem som helst" "Användare kan bara gå med om de är inbjudna" "Endast inbjudan" "Tillgång till rum" - "Utrymmen stöds för närvarande inte" "Utrymmesmedlemmar" - "Du behöver en rumsadress för att göra den synlig i rumskatalogen." + "Utrymmen stöds för närvarande inte" + "Du behöver en rumsadress för att göra den synlig i katalogen." "Tillåt att detta rum hittas genom att söka i den offentliga rumskatalogen på %1$s" "Synlig i katalogen för offentliga rum" + "Vem som helst" "Vem kan läsa historik" "Endast medlemmar sedan de bjöds in" "Endast medlemmar sedan det här alternativet har valts" "Rumsadresser är sätt att hitta och komma åt rum. Detta säkerställer också att du enkelt kan dela ditt rum med andra. Du kan välja att publicera ditt rum i din hemservers offentliga rumskatalog." "Rumspublicering" - "Rumsadresser är sätt att hitta och komma åt rum. Detta säkerställer också att du enkelt kan dela ditt rum med andra. -Adressen krävs också för att göra rummet synligt i%1$s katalog för offentliga rum." "Säkerhet och sekretess" - "Be om att gå med" - "Kryptering" - "Vem som helst" - "Rumssynlighet" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-tr/translations.xml b/features/securityandprivacy/impl/src/main/res/values-tr/translations.xml index 959833c7b6..940fdc9a91 100644 --- a/features/securityandprivacy/impl/src/main/res/values-tr/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-tr/translations.xml @@ -4,35 +4,33 @@ "Oda adresi" "Oda adresi ekle" "Herkes odaya katılma isteğinde bulunabilir ancak bir yönetici veya moderatörün isteği kabul etmesi gerekir." + "Katılmak için sor" "Evet, şifrelemeyi etkinleştir" "Etkinleştirildikten sonra, bir oda için şifreleme devre dışı bırakılamaz, Mesaj geçmişi yalnızca davet edildiklerinden veya odaya katıldıklarından beri oda üyeleri için görünür olacaktır. Oda üyeleri dışında hiç kimse mesajları okuyamayacaktır. Bu, botların ve köprülerin düzgün çalışmasını engelleyebilir. Herkesin bulabileceği ve katılabileceği odalar için şifrelemenin etkinleştirilmesini önermiyoruz." "Şifrelemeyi etkinleştir?" "Açıldıktan donra şifreleme kapatılamaz." + "Şifreleme" "Uçtan uca şifrelemeyi etkinleştir" "Herkes bulabilir ve katılabilir" "Herkes" "İnsanlar yalnızca davet edildiklerinde katılabilirler" "Yalnızca davet" "Oda Erişimi" - "Alanlar şu anda desteklenmiyor" "Alan üyeleri" - "Oda dizininde görünür kılmak için bir oda adresine ihtiyacınız olacaktır." + "Alanlar şu anda desteklenmiyor" + "Dizinde görünür hale getirmek için bir oda adresine ihtiyacınız olacak." "Oda adresi" "Bu odanın %1$s genel oda dizininde arama yapılarak bulunmasına izin verin" "Genel oda dizininde görünür" - "Geçmişi kimler okuyabilir ?" + "Herkes" + "Geçmişi kimler okuyabilir ?" "Sadece üyeler (davet edildiklerinden beri)" "Bu seçeneği seçtiğinden beri yalnızca üyeler" "Oda adresleri, odaları bulmanın ve odalara erişmenin yoludur. Bu aynı zamanda odanızı başkalarıyla kolayca paylaşabilmenizi sağlar. Odanızı ana sunucunuzun genel oda dizininde yayınlamayı seçebilirsiniz." "Oda yayınlama" - "Oda adresleri, odaları bulmanın ve odalara erişmenin yollarıdır. Bu aynı zamanda odanızı başkalarıyla kolayca paylaşabilmenizi sağlar. -Adres, odayı %1$s genel oda dizininde görünür kılmak için de gereklidir." - "Güvenlik ve gizlilik" - "Katılmak için sor" - "Şifreleme" - "Herkes" "Oda görünürlüğü" - \ No newline at end of file + "Güvenlik ve gizlilik" + diff --git a/features/securityandprivacy/impl/src/main/res/values-uk/translations.xml b/features/securityandprivacy/impl/src/main/res/values-uk/translations.xml index b631ee092b..55c7d4fda7 100644 --- a/features/securityandprivacy/impl/src/main/res/values-uk/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-uk/translations.xml @@ -4,35 +4,33 @@ "Адреса кімнати" "Додати адресу кімнати" "Будь-хто може надіслати запит приєднатися до кімнати, але адміністратор або модератор повинні прийняти запит." + "Запросити приєднатися" "Так, увімкнути шифрування" "Після ввімкнення шифрування кімнати, його неможливо вимкнути, історію повідомлень бачитимуть лише учасники кімнати, яких було запрошено або які приєдналися до кімнати. Ніхто, крім учасників кімнати, не зможе прочитати повідомлення. Це може перешкоджати коректній роботі ботів і мостів. Ми не радимо вмикати шифрування для кімнат, які будь-хто може знайти та до яких може приєднатися всі." "Увімкнути шифрування?" "Після ввімкнення шифрування неможливо вимкнути." + "Шифрування" "Увімкнути наскрізне шифрування" "Будь-хто може знайти та приєднатися." - "Будь-хто" + "Кожний" "Люди можуть приєднатися, лише якщо їх запросили" "Лише запрошені" "Доступ до кімнати" - "Простори наразі не підтримуються" "Учасники простору" - "Вам знадобиться адреса кімнати, щоб зробити її видимою в каталозі кімнат." + "Простори наразі не підтримуються" + "Вам знадобиться адреса кімнати, щоб зробити її видимою в каталозі." "Адреса кімнати" "Дозвольте, щоб цю кімнату можна було знайти за допомогою пошуку в каталозі загальнодоступних кімнат %1$s " "Видима в каталозі загальнодоступних кімнат" + "Кожний" "Хто може читати історію" "Лише учасники з моменту запрошення" "Лише учасники після вибору цього параметра" "Адреси кімнат — це спосіб знайти кімнату та отримати до неї доступ. Це також гарантує, що ви можете легко поділитися своєю кімнатою з іншими. Ви можете опублікувати свою кімнату в каталозі загальнодоступних кімнат вашого домашнього сервера." "Публікація в кімнаті" - "Адреси кімнат — це спосіб знайти та отримати доступ до кімнат. Це також гарантує, що ви зможете легко поділитися своєю кімнатою з іншими. -Адреса також необхідна, щоб зробити кімнату видимою в каталозі загальнодоступних кімнат %1$s." - "Безпека й приватність" - "Запросити приєднатися" - "Шифрування" - "Кожний" "Видимість кімнати" - \ No newline at end of file + "Безпека й приватність" + diff --git a/features/securityandprivacy/impl/src/main/res/values-uz/translations.xml b/features/securityandprivacy/impl/src/main/res/values-uz/translations.xml index 157e8f8418..06f0337bf1 100644 --- a/features/securityandprivacy/impl/src/main/res/values-uz/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-uz/translations.xml @@ -1,7 +1,33 @@ + "Katalogda ko‘rinadigan qilish uchun xona manzili kerak bo‘ladi." + "Xona manzili" + "Xona manzilini kiritish" + "Xonaga qo‘shilishni istalgan kishi so‘rashi mumkin, lekin administrator yoki moderator so‘rovni qabul qilishi kerak" "Qo‘shilishni so‘rang" + "Ha, shifrlashni yoqish" + "Yoqilgandan so‘ng, xona uchun shifrlashni o‘chirib bo‘lmaydi. Xabarlar tarixi faqat xona a’zolari taklif qilinganidan yoki xonaga qo‘shilganidan keyingi davrdan boshlab ko‘rinadi. Xona a’zolaridan tashqari hech kim xabarlarni o‘qiy olmaydi. Bu botlar va ko‘priklarning to‘g‘ri ishlashiga to‘sqinlik qilishi mumkin. +Shu sababli, har kim topishi va qo‘shilishi mumkin bo‘lgan xonalar uchun shifrlashni yoqishni tavsiya etmaymiz." + "Shifrlash yoqilsinmi?" + "Yoqilgandan keyin shifrlashni faolsizlantirish imkonsiz." "Shifrlash" + "End-to-end shifrlashni yoqish" + "Istalgan kishi topishi va qo‘shilishi mumkin" + "Har kim" + "Odamlar faqat taklif qilingan taqdirdagina qo‘shilishi mumkin" + "Faqat taklif qilish" + "Xonaga kirish huquqi" + "Maydon a’zolari" + "Hozirda maydonlar qo‘llab-quvvatlanmaydi" + "Katalogda ko‘rinadigan qilish uchun xona manzili kerak bo‘ladi." + "Bu xonani %1$s umumiy xonalar ro‘yxatidan qidirib topish imkoniyatini berish" + "Umumiy xona ro‘yxatida ko‘rinadi" "Har kim" - "Xonaning ko‘rinishi" - \ No newline at end of file + "Tarixni kim o‘qiy oladi" + "Taklif qilinganidan buyon faqat a’zolar" + "A’zolar faqat bu parametr tanlanganidan keyin" + "Xona manzillari xonalarni topish va ularga kirish usullaridir. Bu shuningdek xonangizni boshqalar bilan oson ulashish imkonini beradi. +Xonangizni o‘z homeserveringizning ommaviy xonalar ro‘yxatida e’lon qilishni tanlashingiz mumkin." + "xona nashriyoti" + "Xavfsizlik va maxfiylik" + diff --git a/features/securityandprivacy/impl/src/main/res/values-zh-rTW/translations.xml b/features/securityandprivacy/impl/src/main/res/values-zh-rTW/translations.xml index 44a21456f4..93e5880ae1 100644 --- a/features/securityandprivacy/impl/src/main/res/values-zh-rTW/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-zh-rTW/translations.xml @@ -1,38 +1,37 @@ - "您需要聊天室地址才能在目錄中顯示它。" - "聊天室地址" - "新增聊天室地址" - "任何人都可以要求加入聊天室,但管理員必須接受請求。" + "您需要地址才能在公開目錄中顯示。" + "編輯地址" + "新增地址" + "所有人都必須申請存取權。" + "要求加入" "是的,啟用加密" "啟用後就無法停用聊天室的加密,只有受邀的聊天室成員或加入聊天室後才能看到訊息歷史紀錄。 除了聊天室成員以外,任何人都不能讀取訊息。這可能會讓機器人與橋接無法正常運作。 我們不建議對任何人都可以找到並加入的聊天室啟用加密。" "啟用加密?" "一旦啟用就無法停用加密。" + "加密" "啟用端到端加密" - "任何人都可以找到並加入" + "任何人都可以加入。" "任何人" - "人們僅有受到邀請時才能加入" + "僅受邀者才能加入。" "僅限邀請" - "聊天室存取權" - "目前不支援空間" + "存取權" "空間成員" - "您需要聊天室地址才能在聊天室目錄中顯示。" - "聊天室地址" + "目前不支援空間" + "您需要地址才能在公開目錄中顯示。" + "地址" "允許透過搜尋 %1$s 公開聊天室目錄找到此聊天室" - "在公開聊天室目錄中可見" + "允許其他人透過公開目錄找到。" + "在公開目錄中可見" + "任何人" "誰可以讀取歷史紀錄" "僅在成員被邀請後" "選取此選項後僅限成員" "聊天室地址是尋找與存取聊天室的方法。也確保您可以輕鬆與其他人分享聊天室。 您可以選擇在家伺服器公開聊天室目錄中發佈您的聊天室。" "聊天室發佈" - "聊天室地址是尋找與存取聊天室的方法。也確保您可以輕鬆與其他人分享聊天室。 -若要讓聊天室在 %1$s 公開聊天室目錄中可見,地址也是必要的。" + "能見度" "安全與隱私" - "要求加入" - "加密" - "任何人" - "聊天室能見度" - \ No newline at end of file + diff --git a/features/securityandprivacy/impl/src/main/res/values-zh/translations.xml b/features/securityandprivacy/impl/src/main/res/values-zh/translations.xml index 1dd91a684d..ef9051ab97 100644 --- a/features/securityandprivacy/impl/src/main/res/values-zh/translations.xml +++ b/features/securityandprivacy/impl/src/main/res/values-zh/translations.xml @@ -4,35 +4,33 @@ "房间地址" "添加房间地址" "任何人都可以请求加入房间,但必须由管理员或版主接受请求。" + "请求加入" "是的,启用加密" "一旦启用,就不能再禁用房间的加密功能。消息历史记录只能在房间成员被邀请或加入房间后才可见。 除房间成员外,任何人都无法阅读信息。这可能会妨碍机器人和网桥正常工作。 我们不建议对任何人都能找到并加入的房间启用加密。" "启用加密?" "加密一旦启用,就无法禁用。" + "加密" "启用端到端加密" "任何人都可以找到并加入" "任何人" "只有受邀者才能加入" "仅限邀请" "房间访问权限" - "目前不支持空间" "空间成员" - "你需要有房间地址才能使其在房间目录中可见。" + "目前不支持空间" + "你需要房间地址才能使其在目录中可见。" "房间地址" "允许通过搜索 %1$s 的公共房间目录来发现此房间" "在公共房间目录中可见" + "任何人" "谁可以读取历史记录" "仅限被邀请的成员" "仅自选择此选项以来的成员" "房间地址是查找和访问房间的方式。这也确保你可以轻松地向他人分享房间。 你可以选择在你服务器的公共房间目录中发布你的房间。" "房间发布" - "房间地址是查找和访问房间的方式。这也确保你可以轻松地向他人分享房间。 -在 %1$s 的公共房间目录中显示该房间时也需要地址。" - "安全与隐私" - "请求加入" - "加密" - "任何人" "房间可见性" - \ No newline at end of file + "安全与隐私" + diff --git a/features/securityandprivacy/impl/src/main/res/values/localazy.xml b/features/securityandprivacy/impl/src/main/res/values/localazy.xml index b0e8195733..859be7670b 100644 --- a/features/securityandprivacy/impl/src/main/res/values/localazy.xml +++ b/features/securityandprivacy/impl/src/main/res/values/localazy.xml @@ -2,8 +2,8 @@ "You’ll need an address in order to make it visible in the public directory." "Edit address" - "Add room address" - "Anyone can request access but an administrator must accept the request." + "Add address" + "Everyone must request access." "Ask to join" "Yes, enable encryption" "Once enabled, encryption for a room cannot be disabled, Message history will only be visible for room members since they were invited or since they joined the room. @@ -14,15 +14,18 @@ We do not recommend enabling encryption for rooms that anyone can find and join. "Encryption" "Enable end-to-end encryption" "Anyone can join." - "Public" + "Anyone" + "Choose which spaces’ members can join this room without an invitation. %1$s" + "Manage spaces" "Only invited people can join." - "Private" + "Invite only" "Access" - "Spaces are not currently supported" + "Anyone in authorized spaces can join." + "Anyone in %1$s can join." "Space members" - "You’ll need an address in order to make it visible in the public directory." - "You’ll need a room address in order to make it visible in the room directory." - "Published address" + "Spaces are not currently supported" + "You’ll need an address in order to make it visible in the public directory." + "Address" "Allow for this room to be found by searching %1$s public room directory" "Allow to be found by searching the public directory." "Visible in public directory" @@ -33,8 +36,7 @@ We do not recommend enabling encryption for rooms that anyone can find and join. "Room addresses are ways to find and access rooms. This also ensures you can easily share your room with others. You can choose to publish your room in your homeserver public room directory." "Room publishing" - "Room addresses are ways to find and access rooms. This also ensures you can easily share your room with others. -The address is also required to make the room visible in %1$s public room directory." - "Room visibility" + "Addresses are a way to find and access rooms and spaces. This also ensures you can easily share them with others." + "Visibility" "Security & privacy" diff --git a/features/space/impl/src/main/res/values-cs/translations.xml b/features/space/impl/src/main/res/values-cs/translations.xml index 4a0ecda415..d4730fc62d 100644 --- a/features/space/impl/src/main/res/values-cs/translations.xml +++ b/features/space/impl/src/main/res/values-cs/translations.xml @@ -12,6 +12,6 @@ "Opustit %1$s?" "Jste jediným administrátorem pro %1$s" "Opustit prostor" - "Role a oprávnění" + "Role a oprávnění" "Zabezpečení a soukromí" diff --git a/features/space/impl/src/main/res/values-it/translations.xml b/features/space/impl/src/main/res/values-it/translations.xml index 11ddf1c29b..e483f98513 100644 --- a/features/space/impl/src/main/res/values-it/translations.xml +++ b/features/space/impl/src/main/res/values-it/translations.xml @@ -1,5 +1,16 @@ + "%1$s (Amministratore)" + + "Lascia %1$d stanza e spazio" + "Lascia %1$d stanze e spazi" + + "Seleziona le stanze che desideri abbandonare e di cui non sei l\'unico amministratore:" + "Prima di poter uscire, devi assegnare un altro amministratore a questo spazio." + "Non verrai rimosso dalle seguenti stanze perché sei l\'unico amministratore:" + "Uscire da %1$s?" + "Sei l\'unico amministratore di %1$s" + "Esci dallo spazio" "Ruoli e autorizzazioni" "Sicurezza e privacy" diff --git a/features/space/impl/src/main/res/values-pt-rBR/translations.xml b/features/space/impl/src/main/res/values-pt-rBR/translations.xml index 9c05395704..3329be1097 100644 --- a/features/space/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/space/impl/src/main/res/values-pt-rBR/translations.xml @@ -1,5 +1,16 @@ + "%1$s (Administrador)" + + "Sair de %1$d sala e espaço" + "Sair de %1$d salas e do espaço" + + "Selecione as salas que gostaria de sair nas quais você não é o único administrador:" + "Você precisa atribuir outro administrador para este espaço antes de sair." + "Você não será removido das seguintes salas porque você é o único administrador:" + "Sair de %1$s?" + "Você é o único administrador de %1$s" + "Sair do espaço" "Cargos e permissões" "Segurança e privacidade" diff --git a/features/space/impl/src/main/res/values-uz/translations.xml b/features/space/impl/src/main/res/values-uz/translations.xml index 1fc7fa6b54..83540091ca 100644 --- a/features/space/impl/src/main/res/values-uz/translations.xml +++ b/features/space/impl/src/main/res/values-uz/translations.xml @@ -1,4 +1,5 @@ "Rollar va ruxsatlar" + "Xavfsizlik va maxfiylik" diff --git a/features/startchat/impl/src/main/res/values-uz/translations.xml b/features/startchat/impl/src/main/res/values-uz/translations.xml index a789abc565..b2523ab7bd 100644 --- a/features/startchat/impl/src/main/res/values-uz/translations.xml +++ b/features/startchat/impl/src/main/res/values-uz/translations.xml @@ -3,4 +3,10 @@ "Yangi xona" "Xona katalogi" "Suhbatni boshlashda xatolik yuz berdi" + "Xonaga manzil orqali kirish" + "Yaroqli manzil emas" + "Kirish…" + "Mos xona topildi" + "Xona topilmadi" + "masalan #xona-nomi:matrix.org" diff --git a/features/verifysession/impl/src/main/res/values-pt-rBR/translations.xml b/features/verifysession/impl/src/main/res/values-pt-rBR/translations.xml index 8dd7c9a2f7..591c482ca6 100644 --- a/features/verifysession/impl/src/main/res/values-pt-rBR/translations.xml +++ b/features/verifysession/impl/src/main/res/values-pt-rBR/translations.xml @@ -11,12 +11,12 @@ "Usar outro dispositivo" "Aguardando o outro dispositivo…" "Algo não parece certo. Ou a solicitação atingiu o tempo limite ou a solicitação foi negada." - "Confirme se os emojis abaixo correspondem aos mostrados na sua outra sessão." + "Confirme que os emojis abaixo correspondem aos mostrados no seu outro dispositivo." "Compare os emojis" "Confirme se os emojis abaixo correspondem aos exibidos no dispositivo do outro usuário." "Confirme se os números abaixo correspondem aos mostrados na sua outra sessão." "Comparar números" - "Sua nova sessão está verificada agora. Ela tem acesso às suas mensagens criptografadas e outros usuários a verão como confiável." + "Agora você pode enviar ou receber mensagens com segurança no seu outro dispositivo." "Agora você pode confiar na identidade desse usuário ao enviar ou receber mensagens." "Dispositivo verificado" "Digitar chave de recuperação" @@ -33,7 +33,7 @@ "A verificação falhou" "Continue somente se você iniciou esta verificação." "Verifique o outro dispositivo para manter seu histórico de mensagens seguro." - "Sua nova sessão está verificada agora. Ela tem acesso às suas mensagens criptografadas e outros usuários a verão como confiável." + "Agora você pode enviar ou receber mensagens com segurança no seu outro dispositivo." "Dispositivo verificado" "Verificação solicitada" "Eles não combinam" diff --git a/features/verifysession/impl/src/main/res/values-uz/translations.xml b/features/verifysession/impl/src/main/res/values-uz/translations.xml index 5204e759b3..04169a71d0 100644 --- a/features/verifysession/impl/src/main/res/values-uz/translations.xml +++ b/features/verifysession/impl/src/main/res/values-uz/translations.xml @@ -13,9 +13,11 @@ "Nimadir noto‘g‘ri ko‘rinadi. Yoki so‘rov muddati tugadi yoki so‘rov rad etildi." "Quyidagi kulgichlar boshqa seansda ko‘rsatilganlarga mos kelishini tasdiqlang." "Emojilarni solishtiring" + "Quyidagi emojilar narigi foydalanuvchining qurilmasida ko‘rsatilgan emojilarga mos kelishini tasdiqlang." "Quyidagi raqamlarning boshqa sessiyangizda koʻrsatilgan raqamlarga mos kelishini tasdiqlang." "Sonlarni taqqoslash" "Yangi seansingiz tasdiqlandi. U sizning shifrlangan xabarlaringizga kirish huquqiga ega va boshqa foydalanuvchilar uni ishonchli deb bilishadi." + "Endi xabarlarni yuborish yoki qabul qilishda bu foydalanuvchining shaxsiga ishonishingiz mumkin." "Qurilma tasdiqlandi" "Tiklash kalitini kiriting" "So‘rov vaqti tugab qoldi, so‘rov rad etildi yoki tekshiruv mos kelmadi." @@ -36,6 +38,16 @@ "Tasdiqlash talab qilindi" "Ular mos kelmaydi" "Ular mos keladi" + "Bu yerdan tasdiqlashni boshlashdan oldin, boshqa qurilmada ilovaning ochiq ekanligiga ishonch hosil qiling." + "Ilovani boshqa tasdiqlangan qurilmada oching" + "Qo‘shimcha xavfsizlik chorasi sifatida, qurilmalaringizdagi emojilar to‘plamini solishtirish orqali ushbu foydalanuvchini tasdiqlang. Buni ishonchli aloqa usuli yordamida amalga oshiring." + "Bu foydalanuvchi tasdiqlansinmi?" + "Qo‘shimcha xavfsizlik maqsadida, boshqa foydalanuvchi sizning shaxsingizni tasdiqlashni xohlaydi. Taqqoslash uchun sizga bir qator emojilar ko‘rsatiladi." + "Boshqa qurilmangizda qalqib chiquvchi oyna paydo bo‘lishi kerak. Tekshirish jarayonini o‘sha yerdan boshlang." + "Boshqa qurilmada tekshirishni boshlang" + "Boshqa qurilmada tekshirishni boshlang" + "Boshqa foydalanuvchi kutilmoqda" + "Qabul qilinganingizdan so‘ng, tasdiqlash jarayonini davom ettirishingiz mumkin bo‘ladi." "Davom etish uchun boshqa seansda tekshirish jarayonini boshlash soʻrovini qabul qiling." "Soʻrovni qabul qilish kutilmoqda" "Chiqish…" diff --git a/features/verifysession/impl/src/main/res/values-zh/translations.xml b/features/verifysession/impl/src/main/res/values-zh/translations.xml index 92641d1773..54b6de5d68 100644 --- a/features/verifysession/impl/src/main/res/values-zh/translations.xml +++ b/features/verifysession/impl/src/main/res/values-zh/translations.xml @@ -11,12 +11,12 @@ "使用其他设备" "正在等待其他设备……" "发生了一些错误。网络请求超时,或者被服务器拒绝。" - "确认下方的表情符号与另一设备上显示的相同。" + "确认下面的表情符号与您其他设备上显示的表情符号相匹配。" "比较表情符号" "请验证下方表情是否与对方设备显示一致" "确认以下数字与其他会话中显示的一致。" "比较数字" - "新设备已经成功验证。现在新设备可以访问加密信息,其他用户也会信任这个设备。" + "现在您可以在其他设备上安全地阅读或发送消息。" "现在您可以在发送或接收消息时信任该用户的身份。" "设备已验证" "输入恢复密钥" @@ -33,7 +33,7 @@ "验证失败" "仅在你发起此验证后才继续。" "验证另一台设备以确保您的消息历史记录保密。" - "新设备已经成功验证。现在新设备可以访问加密信息,其他用户也会信任这个设备。" + "现在您可以在其他设备上安全地阅读或发送消息。" "设备已验证" "已请求验证" "不匹配" diff --git a/libraries/eventformatter/impl/src/main/res/values-uz/translations.xml b/libraries/eventformatter/impl/src/main/res/values-uz/translations.xml index 88a8186fec..11835dc605 100644 --- a/libraries/eventformatter/impl/src/main/res/values-uz/translations.xml +++ b/libraries/eventformatter/impl/src/main/res/values-uz/translations.xml @@ -19,6 +19,8 @@ "Siz xonani avatarini o\'chirib tashladingiz" "%1$staqiqlangan%2$s" "Siz taqiqlangansiz%1$s" + "Siz %1$s: %2$sni blokladingiz" + "%1$s %2$s:%3$sni blokladi" "%1$sxonani yaratdi" "Siz xonani yaratdingiz" "%1$staklif qilingan%2$s" @@ -55,6 +57,8 @@ "Siz taklifni rad etdingiz" "%1$s o\'chirildi %2$s" "Siz o\'chirildingiz %1$s" + "Siz olib tashladingiz %1$s :%2$s" + "%1$s %2$s:%3$sni olib tashladi" "%1$s taklifnoma yubordi %2$sga xonaga qo\'shilish uchun" "Siz taklifnoma yubordingiz %1$s ga xonaga qo\'shilishi uchun" "%1$s taklifni %2$s ga xonaga qo\'shilish uchun bekor qildi" diff --git a/libraries/matrixui/src/main/res/values-uz/translations.xml b/libraries/matrixui/src/main/res/values-uz/translations.xml index 069f0b8372..63add2d3c0 100644 --- a/libraries/matrixui/src/main/res/values-uz/translations.xml +++ b/libraries/matrixui/src/main/res/values-uz/translations.xml @@ -1,4 +1,7 @@ + "Taklif yuborish" + "%1$s bilan chatni boshlashni xohlaysizmi?" + "Taklif yuborilsinmi?" "%1$s(%2$s ) sizni taklif qildi" diff --git a/libraries/mediaviewer/impl/src/main/res/values-uz/translations.xml b/libraries/mediaviewer/impl/src/main/res/values-uz/translations.xml new file mode 100644 index 0000000000..8f838c0d26 --- /dev/null +++ b/libraries/mediaviewer/impl/src/main/res/values-uz/translations.xml @@ -0,0 +1,21 @@ + + + "Bu fayl xonadan olib tashlanadi va a’zolar unga kira olmaydilar." + "Fayl oʻchirilsinmi?" + "Internet aloqangizni tekshiring va qayta urining." + "Ushbu xonaga yuklangan hujjatlar, audio fayllar va ovozli xabarlar shu yerda ko‘rsatiladi." + "Hali hech qanday fayl yuklanmagan" + "Fayllar yuklanmoqda…" + "Media yuklanmoqda…" + "Fayllar" + "Media" + "Bu xonaga yuklangan rasm va videolar shu yerda chiqadi." + "Hali hech qanday media yuklanmagan" + "Media va fayllar" + "Fayl formati" + "Fayl nomi" + "Ko‘rsatish uchun boshqa fayllar yo‘q" + "Ko‘rsatish uchun boshqa media yo‘q" + "Tomonidan yuklangan" + "Yuklangan" + diff --git a/libraries/push/impl/src/main/res/values-cs/translations.xml b/libraries/push/impl/src/main/res/values-cs/translations.xml index 8cc5d79095..667f181536 100644 --- a/libraries/push/impl/src/main/res/values-cs/translations.xml +++ b/libraries/push/impl/src/main/res/values-cs/translations.xml @@ -15,6 +15,7 @@ "%d oznámení" "%d oznámení" + "Distributor oznámení UnifiedPush se nepodařilo zaregistrovat, takže již nebudete dostávat oznámení. Zkontrolujte nastavení oznámení v aplikaci a stav distributora push oznámění." "Oznámení" "📹 Příchozí hovor" "** Nepodařilo se odeslat - otevřete prosím místnost" diff --git a/libraries/push/impl/src/main/res/values-fa/translations.xml b/libraries/push/impl/src/main/res/values-fa/translations.xml index da071e07d4..ef24f09c1e 100644 --- a/libraries/push/impl/src/main/res/values-fa/translations.xml +++ b/libraries/push/impl/src/main/res/values-fa/translations.xml @@ -5,15 +5,31 @@ "اعلان‌های پرصدا" "زنگ خوردن تماس" "اعلان‌های صامت" + + "%1$s:%2$d پیام" + "%1$s:%2$d پیام‌" + + + "%dاعلان" + "%dاعلان‌" + "پیام‌های جدیدی دارید." "📹 تماس ورودی" "**‌شکست در فرستادن - لطفاً اتاق را بگشایید" "پیوستن" "رد کردن" + + "%d دعوت" + "%d دعوت" + "به گپ دعوتتان کرد" "%1$s به گپ دعوتتان کرد" "به شما اشاره کرد: %1$s" "پیام جدید" + + "%d پیام جدید" + "%d پیام جدید" + "با %1$s واکنش داد" "علامت‌گذاری به عنوان خوانده شده" "پاسخ سریع" @@ -24,9 +40,17 @@ "دارید آگاهی را مشاهده می‌کنید! کلیک کنید!" "%1$s: %2$s" "%1$s: %2$s %3$s" + + "%d پیام اعلان نشده" + "%d پیام اعلان نشده" + "%1$s و %2$s" "%1$s در %2$s" "%1$s در %2$s و %3$s" + + "%d اتاق" + "%d اتاق" + "همگام سازی پس‌زمینه" "خدمات گوگل" "خدمت پلی گوگل معتبری پیدا نشد. ممکن است آگاهی‌ها به درستی کار نکنند." diff --git a/libraries/push/impl/src/main/res/values-fi/translations.xml b/libraries/push/impl/src/main/res/values-fi/translations.xml index f3cec970d5..1af69c2da9 100644 --- a/libraries/push/impl/src/main/res/values-fi/translations.xml +++ b/libraries/push/impl/src/main/res/values-fi/translations.xml @@ -13,6 +13,7 @@ "%d ilmoitus" "%d ilmoitusta" + "UnifiedPush ilmoitusten jakelijaa ei voitu rekisteröidä, joten et enää vastaanota ilmoituksia. Tarkista sovelluksen ilmoitusasetukset ja push-jakelijan tila." "Sinulle on uusia viestejä." "📹 Saapuva puhelu" "** Lähetys epäonnistui - avaa huone" diff --git a/libraries/push/impl/src/main/res/values-it/translations.xml b/libraries/push/impl/src/main/res/values-it/translations.xml index 6ad3398635..9e44c2d7f9 100644 --- a/libraries/push/impl/src/main/res/values-it/translations.xml +++ b/libraries/push/impl/src/main/res/values-it/translations.xml @@ -13,6 +13,7 @@ "%d notifica" "%d notifiche" + "Non è stato possibile registrare il distributore di notifiche UnifiedPush, quindi non riceverai più notifiche. Controlla le impostazioni delle notifiche dell\'app e lo stato del distributore push." "Hai nuovi messaggi." "📹 Chiamata in arrivo" "** Invio fallito - si prega di aprire la stanza" @@ -38,6 +39,7 @@ "Io" "%1$s ti ha menzionato o risposto" "Stai visualizzando la notifica! Cliccami!" + "Discussione in %1$s" "%1$s: %2$s" "%1$s: %2$s %3$s" @@ -54,9 +56,20 @@ "Sincronizzazione in background" "Servizi Google" "Google Play Services non trovato. Le notifiche non funzioneranno bene." + "Controllo degli utenti bloccati" + "Visualizza gli utenti bloccati" + "Nessun utente è bloccato." + + "Hai bloccato%1$d utente. Non riceverai notifiche da questo utente." + "Hai bloccato%1$d utenti. Non riceverai notifiche da questi utenti." + + "Utenti bloccati" "Ottieni il nome del fornitore attuale." "Nessun provider push selezionato." + "Fornitore push attuale: %1$s e attuale distributore: %2$s Ma il distributore %3$s non viene trovato. Forse l\'applicazione è stata disinstallata?" + "Fornitore push attuale:%1$s , ma non è stato configurato alcun distributore." "Provider push attuale: %1$s." + "Fornitore push attuale: %1$s (%2$s )" "Provider push attuale" "Assicurati che l\'applicazione abbia almeno un fornitore push." "Nessun provider push trovato." diff --git a/libraries/push/impl/src/main/res/values-pt-rBR/translations.xml b/libraries/push/impl/src/main/res/values-pt-rBR/translations.xml index 6d2e96d82c..178823e629 100644 --- a/libraries/push/impl/src/main/res/values-pt-rBR/translations.xml +++ b/libraries/push/impl/src/main/res/values-pt-rBR/translations.xml @@ -13,6 +13,7 @@ "%d notificação" "%d notificações" + "O distribuidor de notificações do UnifiedPush não pôde ser cadastrado, então você não receberá mais notificações. Confira as configurações do app e o estado do distribuidor de push." "Você tem mensagens novas." "📹 Chamada recebida" "** Falha ao enviar - por favor, abra a sala" @@ -38,6 +39,7 @@ "Eu" "%1$s mencionado ou respondido" "Você está visualizando a notificação! Clique em mim!" + "Tópico em %1$s" "%1$s: %2$s" "%1$s: %2$s %3$s" @@ -54,9 +56,20 @@ "Sincronização em segundo plano" "Serviços do Google" "O Google Play Services não foi encontrado. As notificações podem não funcionar corretamente." + "Verificando usuários bloqueados" + "Ver usuários bloqueados" + "Nenhum usuário está bloqueado." + + "Você bloqueou %1$d usuário. Você não receberá notificações deste usuário." + "Você bloqueou %1$d usuários. Você não receberá notificações deles." + + "Usuários bloqueados" "Obtenha o nome do provedor atual." "Nenhum provedor de push foi selecionado." + "Provedor de push atual: %1$s e distribuidor atual: %2$s. Mas o distribuidor %3$s não foi encontrado. Talvez o aplicativo foi desinstalado?" + "Provedor de push atual: %1$s, mas nenhum distribuidor foi configurado." "Provedor de push atual: %1$s." + "Provedor de push atual: %1$s (%2$s)" "Provedor de push atual" "Certifique-se de que o aplicativo tenha suporte a pelo menos um provedor de push." "Nenhum provedor de push com suporte foi encontrado." diff --git a/libraries/push/impl/src/main/res/values-uz/translations.xml b/libraries/push/impl/src/main/res/values-uz/translations.xml index 4a9e4bffbc..7ba9e6319c 100644 --- a/libraries/push/impl/src/main/res/values-uz/translations.xml +++ b/libraries/push/impl/src/main/res/values-uz/translations.xml @@ -64,6 +64,7 @@ "Topildi %1$d push provider: %2$s" "Topildi %1$d push provayderlar: %2$s" + "Ilova quyidagilar uchun yaratilgan: %1$s" "Provayderni qoʻllab-quvvatlash" "Ilova bildirishnomani koʻrsata olishini tekshiring." "Bildirishnoma bosilmagan." @@ -76,4 +77,5 @@ "Xato: %1$s." "Xatolik, push qilishni sinab bo‘lmadi." "Xatolik, taym aut pushni kutmoqda." + "Test Push loop back" diff --git a/libraries/push/impl/src/main/res/values-zh/translations.xml b/libraries/push/impl/src/main/res/values-zh/translations.xml index 2fe8d3e4c7..3f2bd7e836 100644 --- a/libraries/push/impl/src/main/res/values-zh/translations.xml +++ b/libraries/push/impl/src/main/res/values-zh/translations.xml @@ -34,6 +34,7 @@ "我" "%1$s提及或回复" "您正在查看通知!点击我!" + "线程 %1$s" "%1$s:%2$s" "%1$s: %2$s %3$s" @@ -48,12 +49,19 @@ "后台同步" "谷歌服务" "找不到有效的 Google Play 服务。通知可能无法正常工作。" + "检查被阻止的用户" + "查看被屏蔽的用户" + "没有用户被阻止。" "您已屏蔽 %1$d 位用户。您将不再收到这些用户的推送通知。" + "已屏蔽用户" "获取当前推送提供者的名称。" "未选择任何推送提供者。" + "当前推送提供商:%1$s和当前分销商:%2$s . 但经销商%3$s未找到。应用程序可能已被卸载?" + "当前推送提供商:%1$s ,但尚未配置分销商。" "当前推送提供者:%1$s。" + "当前推送提供商:%1$s (%2$s )" "当前推送提供者" "确保应用程序至少有一个推送提供者。" "未找到推送提供者。" diff --git a/libraries/textcomposer/impl/src/main/res/values-uz/translations.xml b/libraries/textcomposer/impl/src/main/res/values-uz/translations.xml index 9b28fd8ef6..d5a7002665 100644 --- a/libraries/textcomposer/impl/src/main/res/values-uz/translations.xml +++ b/libraries/textcomposer/impl/src/main/res/values-uz/translations.xml @@ -5,11 +5,17 @@ "Formatlash parametrlarini yoping" "Kod blokini almashtirish" "Taglavha kiritish" + "Shifrlangan xabar…" "Xabar…" + "Shifrlanmagan xabar…" "Havola yarating" "Havolani tahrirlash" + "%1$s, holat: %2$s" "Qalin formatni qo\'llang" "Kursiv formatini qo\'llang" + "oʻchirilgan" + "o\'chiq" + "yoniq" "Chizilgan formatni qo\'llash" "Pastki chiziq formatini qo\'llang" "Toʻliq ekran rejimiga oʻtish" @@ -22,5 +28,6 @@ "Havolani olib tashlang" "Paragrafni bekor qilish" "Havola" + "Taglavhalar eski ilovalardan foydalanuvchilarga ko‘rinmasligi mumkin." "Yozib olish uchun bosib turing" diff --git a/libraries/troubleshoot/impl/src/main/res/values-uz/translations.xml b/libraries/troubleshoot/impl/src/main/res/values-uz/translations.xml index e01e098f5f..d7fa7207e7 100644 --- a/libraries/troubleshoot/impl/src/main/res/values-uz/translations.xml +++ b/libraries/troubleshoot/impl/src/main/res/values-uz/translations.xml @@ -1,5 +1,6 @@ + "Bildirishnoma tarixi" "Testlarni ishga tushirish" "Testlarni qayta ishga tushirish" "Ba’zi testlar muvaffaqiyatsiz tugadi. Iltimos, tafsilotlarni tekshirib chiqing." diff --git a/libraries/ui-strings/src/main/res/values-cs/translations.xml b/libraries/ui-strings/src/main/res/values-cs/translations.xml index ccc293a691..d4f8550f7a 100644 --- a/libraries/ui-strings/src/main/res/values-cs/translations.xml +++ b/libraries/ui-strings/src/main/res/values-cs/translations.xml @@ -452,6 +452,10 @@ Opravdu chcete pokračovat?" "Vaše zpráva nebyla odeslána, protože%1$s neověřil(a) všechna zařízení" "Jedno nebo více vašich zařízení není ověřeno. Zprávu můžete přesto odeslat, nebo ji můžete prozatím zrušit a zkusit to znovu později, až ověříte všechna svá zařízení." "Vaše zpráva nebyla odeslána, protože jste neověřili jedno nebo více zařízení" + "Změnit nastavení" + "Správa prostoru" + "Spravovat místnosti" + "Oprávnění" "Upravit správce nebo vlastníky" "Nahrání média se nezdařilo, zkuste to prosím znovu." "Nepodařilo se načíst údaje o uživateli" diff --git a/libraries/ui-strings/src/main/res/values-fa/translations.xml b/libraries/ui-strings/src/main/res/values-fa/translations.xml index 6f55ce0db4..1656bc3b0c 100644 --- a/libraries/ui-strings/src/main/res/values-fa/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fa/translations.xml @@ -3,6 +3,10 @@ "افزودن واکنش: %1$s" "چهرک" "حذف" + + "%1$d رقم وارد شده" + "%1$d رقم وارد شده" + "ویرایش چهرک" "نشانی کامل %1$s خواهد بود" "جزییات رمزنگاری" @@ -26,6 +30,10 @@ "واکنش با %1$s" "واکنش با شکلک‌های دیگر" "خوانده به دست %1$s و %2$s" + + "خوانده شده توسط%1$s و%2$d نفر دیگر" + "خوانده شده توسط%1$s و%2$d نفر دیگر" + "خوانده به دست %1$s" "زدن برای نمایش همه" "برداشتن واکنش با %1$s" @@ -112,7 +120,7 @@ "نقل قول" "واکنش" "رد کردن" - "برداشتن" + "حذف" "برداشتن عنوان" "برداشتن پیام‌ها" "پاسخ" @@ -216,6 +224,10 @@ "پیوند در تخته‌گیره رونوشت شد" "بار کردن…" "بار کردن بیش‌تر…" + + "%1$d عضو" + "%1$d عضو" + "پیام" "کنش‌های پیام" "جینش پیام" @@ -241,6 +253,10 @@ "نظرسنجی: %1$s" "مجموع آرا: %1$s" "نتیجه‌ها پس از پایان نظرسنجی نشان داده خواهند شد" + + "%d رأی" + "%d رأی" + "آماده سازی…" "سیاست محرمانگی" "اتاق خصوصی" diff --git a/libraries/ui-strings/src/main/res/values-fi/translations.xml b/libraries/ui-strings/src/main/res/values-fi/translations.xml index 1885f56f66..bc23e78b05 100644 --- a/libraries/ui-strings/src/main/res/values-fi/translations.xml +++ b/libraries/ui-strings/src/main/res/values-fi/translations.xml @@ -95,10 +95,11 @@ "Unohditko salasanan?" "Välitä" "Takaisin" + "Siirry rooleihin ja oikeuksiin" "Siirry asetuksiin" "Ohita" "Kutsu" - "Kutsu ihmisiä" + "Kutsu henkilöitä" "Kutsu ihmisiä %1$s -sovellukseen" "Kutsu ihmisiä %1$s -sovellukseen" "Kutsut" @@ -444,6 +445,10 @@ Haluatko varmasti jatkaa?" "Viestiäsi ei lähetetty, koska %1$s ei ole vahvistanut kaikkia laitteitaan." "Yksi tai useampi laitteistasi on vahvistamaton. Voit lähettää viestin silti tai peruuttaa sen toistaiseksi ja yrittää uudelleen myöhemmin, kun olet vahvistanut kaikki laitteesi." "Viestiäsi ei lähetetty, koska et ole vahvistanut yhtä tai useampaa laitettasi." + "Asetusten muuttaminen" + "Tilan hallitseminen" + "Huoneiden hallitseminen" + "Oikeudet" "Muokkaa ylläpitäjiä tai omistajia" "Median käsittely epäonnistui, yritä uudelleen." "Käyttäjän tietojen hakeminen epäonnistui" diff --git a/libraries/ui-strings/src/main/res/values-it/translations.xml b/libraries/ui-strings/src/main/res/values-it/translations.xml index 77a1a20782..793b115917 100644 --- a/libraries/ui-strings/src/main/res/values-it/translations.xml +++ b/libraries/ui-strings/src/main/res/values-it/translations.xml @@ -42,7 +42,7 @@ "Rimuovere la reazione con %1$s" "Avatar della stanza" "Invia file" - "Azione a tempo limitato richiesta" + "Azione richiesta a tempo limitato, hai un minuto per la verifica" "Mostra password" "Avvia una chiamata" "Stanza obsoleta" @@ -80,6 +80,7 @@ "Rifiuta" "Rifiuta e blocca" "Elimina sondaggio" + "Deseleziona tutti" "Disabilita" "Annulla" "Chiudi" @@ -94,6 +95,8 @@ "Password dimenticata?" "Inoltra" "Indietro" + "Vai a ruoli & autorizzazioni" + "Vai alle impostazioni" "Ignora" "Invita" "Invita persone" @@ -105,10 +108,12 @@ "Esci" "Abbandona la conversazione" "Esci dalla stanza" + "Esci dallo spazio" "Carica altro" "Gestisci account" "Gestisci dispositivi" "Invia messaggio" + "Riduci" "Avanti" "No" "Non ora" @@ -137,6 +142,7 @@ "Riprova la decrittazione" "Salva" "Ricerca" + "Seleziona tutti" "Invia" "Invia messaggio modificato" "Invia messaggio" @@ -165,6 +171,8 @@ "Aggiornamento disponibile" "Informazioni" "Regole sull\'utilizzo consentito" + "Aggiungi un account" + "Aggiungi un altro account" "Aggiunta didascalia" "Impostazioni avanzate" "un\'immagine" @@ -173,6 +181,7 @@ "Sei stato disconnesso dalla sessione" "Aspetto" "Audio" + "Beta" "Utenti bloccati" "Fumetti" "Chiamata avviata" @@ -182,9 +191,11 @@ "Creazione stanza…" "Richiesta annullata" "Hai lasciato la stanza" + "Hai lasciato lo spazio" "Invito rifiutato" "Scuro" "Errore di decrittazione" + "Descrizione" "Opzioni sviluppatore" "ID dispositivo" "Conversazione diretta" @@ -219,6 +230,7 @@ Motivo:. %1$s" "Installa APK" "Questo ID Matrix non può essere trovato, quindi l\'invito potrebbe non essere ricevuto." "Lascio la stanza" + "Uscendo dallo spazio" "Chiaro" "Riga copiata negli appunti" "Collegamento copiato negli appunti" @@ -241,6 +253,7 @@ Motivo:. %1$s" "%1$s (%2$s)" "Nessun risultato" "Nessun nome della stanza" + "Spazio senza nome" "Non cifrato" "Non in linea" "Licenze open source" @@ -294,15 +307,19 @@ Motivo:. %1$s" "Risultati di ricerca" "Sicurezza" "Visto da" + "Seleziona un account" "Invia a" "Invio in corso…" "Invio fallito" "Inviato" "." "Server non supportato" + "Server non raggiungibile" "URL del server" "Impostazioni" + "Condividi lo spazio" "Posizione condivisa" + "Spazio condiviso" "Disconnessione" "Qualcosa è andato storto" "Abbiamo riscontrato un problema. Per favore riprova." @@ -376,6 +393,8 @@ Sei sicuro di voler continuare?" "La dimensione massima consentita per il file è: %1$s" "Seleziona la qualità del video che vuoi caricare." "Seleziona la qualità di caricamento del video" + "Cerca emoji" + "Hai già effettuato l\'accesso su questo dispositivo come %1$s ." "Il tuo homeserver deve essere aggiornato per supportare il Matrix Authentication Service e la creazione di account." "Impossibile creare il collegamento permanente" "%1$s non è riuscito a caricare la mappa. Riprova più tardi." @@ -426,6 +445,10 @@ Sei sicuro di voler continuare?" "Il tuo messaggio non è stato inviato perché %1$s non ha verificato tutti i dispositivi." "Uno o più dispositivi non sono verificati. Puoi inviare il messaggio comunque, oppure annullarlo e riprovare più tardi dopo aver verificato tutti i tuoi dispositivi." "Il tuo messaggio non è stato inviato perché non hai verificato uno o più dispositivi." + "Modifica impostazioni" + "Gestire lo spazio" + "Gestisci le stanze" + "Autorizzazioni" "Modifica amministratori o proprietari" "Elaborazione del file multimediale da caricare fallita, riprova." "Impossibile recuperare i dettagli dell\'utente" @@ -446,7 +469,9 @@ Sei sicuro di voler continuare?" "Condividi questa posizione" "Spazi che hai creato o a cui hai aderito." "%1$s • %2$s" + "%1$s spazio" "Spazi" + "Visualizza membri" "Messaggio non inviato perché l\'identità verificata di %1$s è stata reimpostata." "Messaggio non inviato perché %1$s non ha verificato tutti i dispositivi." "Messaggio non inviato perché non hai verificato uno o più dispositivi." diff --git a/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml b/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml index fabc600b67..2f9b4a13e8 100644 --- a/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml +++ b/libraries/ui-strings/src/main/res/values-pt-rBR/translations.xml @@ -2,6 +2,7 @@ "Adicionar reação: %1$s" "Avatar" + "Minimizar campo de texto de mensagem" "Apagar" "%1$d dígito digitado" @@ -10,6 +11,7 @@ "Editar avatar" "O endereço completo será %1$s" "Detalhes de criptografia" + "Expandir campo de texto de mensagem" "Ocultar senha" "Entrar à chamada" "Ir para o final" @@ -40,7 +42,7 @@ "Remover reação com %1$s" "Avatar da sala" "Enviar arquivos" - "Ação de tempo limitado necessária" + "Ação de tempo limitado necessária, você tem um minuto para verificar" "Mostrar senha" "Iniciar uma chamada" "Sala morta" @@ -78,6 +80,7 @@ "Recusar" "Recusar e bloquear" "Excluir enquete" + "Desselecionar tudo" "Desativar" "Descartar" "Dispensar" @@ -88,9 +91,12 @@ "Ativar" "Encerrar enquete" "Digitar PIN" + "Concluir" "Esqueceu a senha?" "Encaminhar" "Voltar" + "Ir aos cargos e permissões" + "Ir às configurações" "Ignorar" "Convidar" "Convidar pessoas" @@ -102,10 +108,12 @@ "Sair" "Sair da conversa" "Sair da sala" + "Sair do espaço" "Carregar mais" "Gerenciar conta" "Gerenciar dispositivos" "Mensagem" + "Minimizar" "Avançar" "Não" "Agora não" @@ -134,6 +142,7 @@ "Tentar descriptografar novamente" "Salvar" "Pesquisar" + "Selecionar tudo" "Enviar" "Enviar mensagem editada" "Enviar mensagem" @@ -162,12 +171,17 @@ "Atualização disponível" "Sobre" "Política de uso aceitável" + "Adicionar uma conta" + "Adicionar outra conta" "Adicionando legenda" "Configurações avançadas" "uma imagem" "Telemetria" + "Você saiu da sala" + "Você foi desconectado da sessão" "Aparência" "Áudio" + "Beta" "Usuários bloqueados" "Balões" "Chamada iniciada" @@ -177,9 +191,11 @@ "Criando sala…" "Solicitação cancelada" "Saiu da sala" + "Saiu do espaço" "Convite recusado" "Escuro" "Erro de descriptografia" + "Descrição" "Opções de desenvolvedor" "ID do dispositivo" "Conversa direta" @@ -214,6 +230,7 @@ Motivo:​ %1$s." "Instalar APK" "Este ID Matrix não foi encontrado, então o convite pode não ser recebido" "Saindo da sala" + "Saindo do espaço" "Claro" "Linha copiada para a área de transferência" "Link copiado para área de transferência" @@ -236,6 +253,7 @@ Motivo:​ %1$s." "%1$s (%2$s)" "Não há resultados" "Não há um nome para a sala" + "Sem nome de espaço" "Sem criptografia" "Off-line" "Licenças de código aberto" @@ -289,18 +307,23 @@ Motivo:​ %1$s." "Resultados da pesquisa" "Segurança" "Visto por" + "Selecionar uma conta" "Enviar para" "Enviando…" "Envio falhou" "Enviado" ". " "Servidor não suportado" + "Servidor inacessível" "URL do servidor" "Configurações" + "Compartilhar espaço" "Localização compartilhada" + "Espaço compartilhado" "Saindo" "Algo deu errado" "Encontramos um problema. Tente novamente." + "Espaço" "%1$d espaço" "%1$d espaços" @@ -335,6 +358,12 @@ Motivo:​ %1$s." "Verificar identidade" "Verificar usuário" "Vídeo" + "Alta qualidade" + "Melhor qualidade, mas tamanho de arquivo maior" + "Baixa qualidade" + "Maior velocidade de envio e menor tamanho de arquivo" + "Qualidade normal" + "Equilíbrio entre qualidade e velocidade de envio" "Mensagem de voz" "Aguardando…" "Aguardando por esta mensagem" @@ -349,6 +378,10 @@ Motivo:​ %1$s." Você tem certeza de que deseja continuar?" "Verifique este link duas vezes" + "Selecione a qualidade padrão dos videos que você envia." + "Qualidade de envio de vídeos" + "O tamanho máximo permitido de arquivos é: %1$s" + "O tamanho do arquivo é muito grande para ser enviado" "Sala denunciada" "Denunciou e deixou a sala" "Confirmação" @@ -357,6 +390,11 @@ Você tem certeza de que deseja continuar?" "Alerta" "Suas alterações não foram salvas. Tem certeza de que você quer voltar?" "Salvar alterações?" + "O tamanho máximo permitido de arquivos é: %1$s" + "Selecione a qualidade do video que quer enviar." + "Selecione a qualidade de envio dos vídeos" + "Pesquisar emojis" + "Você já está conectado neste dispositivo como %1$s ." "Seu servidor-casa precisa ser atualizado para oferecer suporte ao Matrix Authentication Service e à criação de contas." "Falha ao criar o link permanente" "%1$s não conseguiu carregar o mapa. Por favor, tente novamente mais tarde." @@ -407,6 +445,10 @@ Você tem certeza de que deseja continuar?" "Sua mensagem não foi enviada porque %1$s não verificou todos os dispositivos" "Um ou mais de seus dispositivos não foram verificados. Você pode enviar a mensagem mesmo assim ou pode cancelar por enquanto e tentar novamente mais tarde, depois de ter verificado todos os seus dispositivos." "Sua mensagem não foi enviada porque você não verificou um ou mais de seus dispositivos" + "Alterar configurações" + "Gerenciar espaço" + "Gerenciar salas" + "Permissões" "Editar administradores ou proprietários" "Falha ao processar a mídia para o envio. Tente novamente." "Não foi possível buscar os detalhes do usuário" @@ -427,7 +469,9 @@ Você tem certeza de que deseja continuar?" "Compartilhar esta localização" "Os espaços que você criou ou entrou." "%1$s • %2$s" + "Espaço %1$s" "Espaços" + "Ver membros" "Mensagem não enviada porque a identidade verificada de %1$s foi redefinida." "A mensagem não foi enviada porque %1$s não verificou todos os dispositivos." "Mensagem não enviada porque você não verificou um ou mais dos seus dispositivos." diff --git a/libraries/ui-strings/src/main/res/values-uz/translations.xml b/libraries/ui-strings/src/main/res/values-uz/translations.xml index 40da86f9d5..8f23ee0d9e 100644 --- a/libraries/ui-strings/src/main/res/values-uz/translations.xml +++ b/libraries/ui-strings/src/main/res/values-uz/translations.xml @@ -2,6 +2,7 @@ "Reaksiya qoʻyish: %1$s" "Avatar" + "Xabar matni maydonini kichraytirish" "Oʻchirish" "%1$d ta raqam kiritildi" @@ -10,6 +11,7 @@ "Avatarni tahrirlash" "To\'liq manzil %1$s bo\'ladi" "Shifrlash tafsilotlari" + "Xabar matni maydonini kengaytirish" "Parolni yashirish" "Qoʻngʻiroqga qoʻshilish" "Pastga o\'tish" @@ -40,7 +42,7 @@ "%1$s bilan reaktsiyani olib tashlang" "Xona avatari" "Fayllarni yuborish" - "Vaqt cheklangan harakat talab qilinadi" + "Amal bajarish vaqti cheklangan, tasdiqlash uchun bir daqiqa vaqtingiz bor" "Parolni ko\'rsatish" "Qoʻngʻiroqni boshlash" "Arxivlangan xona" @@ -88,6 +90,7 @@ "Yoqish" "So‘rovnomani tugatish" "PIN kodni kiriting" + "Tugatish" "Parolni unutdingizmi?" "Oldinga" "Ortga qaytish" @@ -162,10 +165,14 @@ "Yangilash mavjud" "Haqida" "Qabul qilinadigan foydalanish siyosati" + "Hisob qo‘shish" + "Boshqa hisob qo‘shish" "Sarlavha qoʻshish" "Kengaytirilgan sozlamalar" "rasm" "Analitika" + "Siz xonani tark etdingiz" + "Siz sessiyadan chiqdingiz" "Ko\'rinish" "Audio" "Bloklangan foydalanuvchilar" @@ -180,6 +187,7 @@ "Taklif rad etildi" "Tungi" "Shifrni ochish xatosi" + "Tavsif" "Dasturchi variantlari" "Qurilma ID" "Shaxsiy suhbat" @@ -258,12 +266,18 @@ Sababi:%1$s." "Tayyorlanmoqda…" "Maxfiylik siyosati" "Shaxsiy xona" + "Shaxsiy guruh" "Jamoat xonasi" + "Jamoat guruhi" "Reaktsiya" "reaksiyalar" "Sabab" "Qayta tiklash kaliti" "Yangilanmoqda…" + + "%1$d ta javob" + "%1$d ta javob" + "%1$sga Javob berilmoqda" "Xato haqida xabar bering" "Muammo haqida xabar bering" @@ -272,6 +286,10 @@ Sababi:%1$s." "Xona" "Xona nomi" "masalan, loyihangiz nomi" + + "%1$d Xona" + "%1$d Xonalar" + "Saqlangan oʻzgarishlar" "Saqlash" "Ekran qulfi" @@ -279,18 +297,25 @@ Sababi:%1$s." "Qidiruv natijalari" "Xavfsizlik" "Tomonidan koʻrilgan" + "Hisobni tanlang" "Yubirish" "Yuborilmoqda…" "Yuborilmadi" "Yuborilgan" ". " "Server qo\'llab-quvvatlanmaydi" + "Serverga kirish imkonsiz" "Server URL manzili" "Sozlamalar" "Joylashuvi ulashildi" "Chiqish" "Nimadir xato ketdi" "Muammoga duch keldik. Iltimos, qayta urinib koʻring." + "Bo‘shliq" + + "%1$d Guruh" + "%1$d Guruhlar" + "Chat boshlanmoqda…" "Stiker" "Muvaffaqiyat" @@ -310,6 +335,7 @@ Sababi:%1$s." "Taklif(lar)ni yuborib bo‘lmadi" "Qulfni ochish" "Ovozni yoqish" + "Qo‘llab-quvvatlanmaydigan chaqiruv" "Qo\'llab-quvvatlanmagan hodisa" "Foydalanuvchi nomi" "Tasdiqlash bekor qilindi" @@ -318,31 +344,62 @@ Sababi:%1$s." "Tasdiqlangan" "Qurilmani tasdiqlash" "Shaxsni tasdiqlash" + "Foydalanuvchini tasdiqlang" "Video" + "Yuqori sifatli" + "Eng yaxshi sifat, lekin kattaroq fayl hajmi" + "Past sifat" + "Eng tez yuklash tezligi va eng kichik fayl hajmi" + "Standart sifat" + "Sifat va yuklash tezligi balansi" "Ovozli xabar" "Kutilmoqda…" "Ushbu xabarni kutilmoqda" "Siz" "%1$sning shaxsi qayta tiklandi.%2$s" + "%1$sʼning %2$s shaxsiy ma’lumotlari qayta tiklandi.%3$s" "(%1$s )" + "%1$sning shaxsi qayta tiklandi." + "%1$sʼning %2$s shaxsiy ma’lumotlari qayta o‘rnatildi.%3$s" + "Tasdiqlashni bekor qilish" + "%1$s havolasi sizni boshqa %2$s saytiga olib boradi + +Davom etasizmi?" + "Ushbu havolani ikki marta tekshiring" + "Yuklagan videolaringizning standart sifatini tanlang." + "Video yuklash sifati" + "Ruxsat etilgan maksimal fayl hajmi: %1$s" + "Fayl hajmi yuklash uchun juda katta" + "Xona haqida xabar" + "Xabar berildi va xona tark etildi" "Tasdiqlash" "Xato" "Muvaffaqiyat" "Ogohlantirish" "Oʻzgarishlar saqlanmadi. Haqiqatan ham orqaga qaytmoqchimisiz?" "O‘zgartirishlarni saqlaysizmi?" + "Ruxsat etilgan maksimal fayl hajmi: %1$s" + "Yuklanadigan video sifatini tanlang." + "Video yuklash sifatini tanlang" + "Emojilarni qidiring" + "Bu qurilmada allaqachon %1$s hisobiga kirgansiz." "Matrix autentifikatsiya xizmati va hisob yaratish imkoniyatini qo‘llab-quvvatlash uchun uy serveringizni yangilash talab etiladi." "Doimiy havola yaratilmadi" "%1$sxaritani yuklay olmadi. Iltimos keyinroq qayta urinib ko\'ring." "Xabarlar yuklanmadi" "%1$sjoylashuvingizga kira olmadi. Iltimos keyinroq qayta urinib ko\'ring." "Ovozli xabaringizni yuklashda xatolik roʻy berdi." + "Xona endi mavjud emas yoki taklif yaroqsiz." "Xabar topilmadi" "%1$sjoylashuvingizga kirishga ruxsati yo\'q. Sozlamalar orqali kirishni yoqishingiz mumkin." "%1$sjoylashuvingizga kirishga ruxsati yo\'q. Quyida kirishni yoqing." "%1$smikrofoningizga kirish ruxsatiga ega emas. Ovozli xabar yozish uchun ruxsatni yoqing." + "Bu tarmoq yoki server muammolari bilan bog‘liq bo‘lishi mumkin." + "Bu xona manzili allaqachon mavjud. Xona manzili maydonini tahrirlang yoki xona nomini o‘zgartiring" + "Ayrim belgilarga ruxsat berilmagan. Faqat harf, raqam va quyidagi belgilar ishlaydi! $ &’() * + /; =? @ [ ] -. _" "Bazi xabarlar yuborilmagan" "Kechirasiz, xatolik yuz berdi" + "Hodisani yuborgan shaxs uni yuborgan qurilmaning egasi bilan mos kelmaydi." "Bu qurilmada shifrlangan xabarning haqiqiyligini kafolatlash imkonsiz." "Avval tasdiqlangan foydalanuvchi tomonidan shifrlangan." "Shifrlanmagan" @@ -353,6 +410,11 @@ Sababi:%1$s." "Hey, men bilan gaplash%1$s :%2$s" "%1$sAndroid" "Xato haqida xabar berish uchun G\'azablanish" + "Skrinshot" + "%1$s:%2$s" + "Parametrlar" + "%1$sni olib tashlash" + "Sozlamalar" "Media tanlash jarayonida xatolik yuz berdi, qayta urinib ko\'ring" "Xabarni bosib, bu yerga kiritish uchun \"%1$s\"-ni tanlang." "Muhim xabarlarni osongina topish uchun qadang" @@ -371,8 +433,13 @@ Sababi:%1$s." "%1$s barcha qurilmalarni tasdiqlamagani uchun xabaringiz yuborilmadi" "Bir yoki bir nechta qurilmangiz tasdiqlanmagan. Xabarni istalgancha yuborishingiz yoki hozircha bekor qilishingiz va barcha qurilmalaringizni tasdiqlaganingizdan keyin qayta urinishingiz mumkin." "Xabaringiz yuborilmadi, chunki bir yoki bir nechta qurilmangizni tasdiqlamagansiz" + "Administratorlar yoki egalarni tahrirlash" "Mediani yuklab bo‘lmadi, qayta urinib ko‘ring." "Foydalanuvchi tafsilotlarini olinmadi" + "Xabar %1$sda" + "Kengaytirish" + "Kamaytirish" + "Bu xona allaqachon ko‘rilmoqda!" "%1$sʼdan %2$s" "%1$s ta qadalgan xabar" "Xabar yuklanmoqda…" @@ -384,11 +451,18 @@ Sababi:%1$s." "Google Mapsda oching" "OpenStreetMapda oching" "Bu joylashuvni ulashing" + "Siz yaratgan yoki qo‘shilgan guruhlar." + "%1$s•%2$s" + "Bo‘shliqlar" "Xabar yuborilmadi, chunki %1$sʼning tasdiqlangan identifikatori asliga qaytarildi." "Xabar yuborilmadi, chunki %1$s barcha qurilmalarni tasdiqlamagan." "Xabaringiz yuborilmadi, chunki siz bir yoki bir nechta qurilmangizni tasdiqlamagan ekansiz." "Joylashuv" "Versiya:%1$s (%2$s )" "en" + "Bu qurilmada tarixiy xabarlar mavjud emas" + "Tarixiy xabarlarga kirish uchun bu qurilmani tasdiqlashingiz kerak" "Sizni ushbu xabarga ruxsatingiz yoʻq" + "Xabarni shifrini ochib bo‘lmadi" + "Bu xabar bloklandi, chunki siz qurilmangizni tasdiqlamadingiz yoki yuboruvchi shaxsingizni tasdiqlashi kerak bo‘lgani sababli bloklandi" diff --git a/libraries/ui-strings/src/main/res/values-zh/translations.xml b/libraries/ui-strings/src/main/res/values-zh/translations.xml index a4144eb8f0..a743a5771b 100644 --- a/libraries/ui-strings/src/main/res/values-zh/translations.xml +++ b/libraries/ui-strings/src/main/res/values-zh/translations.xml @@ -93,6 +93,8 @@ "忘记密码?" "转发" "返回" + "前往角色与权限" + "前往设置" "忽略" "邀请" "邀请朋友" @@ -177,6 +179,7 @@ "您已被注销当前会话" "外观" "音频" + "测试版" "已屏蔽用户" "气泡" "通话已开始" @@ -307,7 +310,9 @@ "无法访问服务器" "服务器 URL" "设置" + "共享空间" "共享位置" + "共享空间" "正在登出" "发生了一些错误" "我们遇到了一个问题。请重试。" @@ -451,7 +456,9 @@ "分享这个位置" "您创建或加入的空间。" "%1$s • %2$s" + "%1$s空间" "空间" + "查看成员" "消息未发送,因为%1$s的已验证身份已被重置。" "消息未发送,因为%1$s尚未验证所有设备。" "消息未发送,因为您有尚未验证的设备。" diff --git a/libraries/ui-strings/src/main/res/values/localazy.xml b/libraries/ui-strings/src/main/res/values/localazy.xml index b1586a8d66..dcd3cdd6e2 100644 --- a/libraries/ui-strings/src/main/res/values/localazy.xml +++ b/libraries/ui-strings/src/main/res/values/localazy.xml @@ -246,6 +246,7 @@ Reason: %1$s." "Message" "Message actions" + "Message failed to send" "Message layout" "Message removed" "Modern" @@ -368,6 +369,7 @@ Reason: %1$s." "Waiting…" "Waiting for this message" "You" + "Messages you send will be shared with new members invited to this room. %1$s" "%1$s\'s identity was reset. %2$s" "%1$s’s %2$s identity was reset. %3$s" "(%1$s)" @@ -427,6 +429,11 @@ Are you sure you want to continue?" "Options" "Remove %1$s" "Settings" + "Spaces where members can join the room without an invitation." + "Manage spaces" + "(Unknown space)" + "Other spaces you’re not a member of" + "Your spaces" "Failed selecting media, please try again." "Press on a message and choose “%1$s” to include here." "Pin important messages so that they can be easily discovered" diff --git a/screenshots/html/data.js b/screenshots/html/data.js index 6d8ee5fbab..758b77c7ee 100644 --- a/screenshots/html/data.js +++ b/screenshots/html/data.js @@ -1,80 +1,80 @@ // Generated file, do not edit export const screenshots = [ ["en","en-dark","de",], -["features.preferences.impl.about_AboutView_Day_0_en","features.preferences.impl.about_AboutView_Night_0_en",20413,], +["features.preferences.impl.about_AboutView_Day_0_en","features.preferences.impl.about_AboutView_Night_0_en",20420,], ["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_0_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_0_en",0,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_1_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_1_en",20413,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20413,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20413,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20413,], -["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20413,], -["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20413,], -["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20413,], -["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20413,], -["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20413,], -["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20413,], -["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20413,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_1_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_1_en",20420,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_2_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_2_en",20420,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_3_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_3_en",20420,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_4_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_4_en",20420,], +["features.invite.impl.acceptdecline_AcceptDeclineInviteView_Day_5_en","features.invite.impl.acceptdecline_AcceptDeclineInviteView_Night_5_en",20420,], +["features.logout.impl_AccountDeactivationView_Day_0_en","features.logout.impl_AccountDeactivationView_Night_0_en",20420,], +["features.logout.impl_AccountDeactivationView_Day_1_en","features.logout.impl_AccountDeactivationView_Night_1_en",20420,], +["features.logout.impl_AccountDeactivationView_Day_2_en","features.logout.impl_AccountDeactivationView_Night_2_en",20420,], +["features.logout.impl_AccountDeactivationView_Day_3_en","features.logout.impl_AccountDeactivationView_Night_3_en",20420,], +["features.logout.impl_AccountDeactivationView_Day_4_en","features.logout.impl_AccountDeactivationView_Night_4_en",20420,], +["features.login.impl.accountprovider_AccountProviderOtherView_Day_0_en","features.login.impl.accountprovider_AccountProviderOtherView_Night_0_en",20420,], ["features.login.impl.accountprovider_AccountProviderView_Day_0_en","features.login.impl.accountprovider_AccountProviderView_Night_0_en",0,], ["features.login.impl.accountprovider_AccountProviderView_Day_1_en","features.login.impl.accountprovider_AccountProviderView_Night_1_en",0,], ["features.login.impl.accountprovider_AccountProviderView_Day_2_en","features.login.impl.accountprovider_AccountProviderView_Night_2_en",0,], ["features.login.impl.accountprovider_AccountProviderView_Day_3_en","features.login.impl.accountprovider_AccountProviderView_Night_3_en",0,], -["libraries.accountselect.impl_AccountSelectView_Day_0_en","libraries.accountselect.impl_AccountSelectView_Night_0_en",20413,], -["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20413,], +["libraries.accountselect.impl_AccountSelectView_Day_0_en","libraries.accountselect.impl_AccountSelectView_Night_0_en",20420,], +["libraries.accountselect.impl_AccountSelectView_Day_1_en","libraries.accountselect.impl_AccountSelectView_Night_1_en",20420,], ["features.messages.impl.actionlist_ActionListViewContent_Day_0_en","features.messages.impl.actionlist_ActionListViewContent_Night_0_en",0,], -["features.messages.impl.actionlist_ActionListViewContent_Day_10_en","features.messages.impl.actionlist_ActionListViewContent_Night_10_en",20413,], -["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20413,], -["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20413,], +["features.messages.impl.actionlist_ActionListViewContent_Day_10_en","features.messages.impl.actionlist_ActionListViewContent_Night_10_en",20420,], +["features.messages.impl.actionlist_ActionListViewContent_Day_11_en","features.messages.impl.actionlist_ActionListViewContent_Night_11_en",20420,], +["features.messages.impl.actionlist_ActionListViewContent_Day_12_en","features.messages.impl.actionlist_ActionListViewContent_Night_12_en",20420,], ["features.messages.impl.actionlist_ActionListViewContent_Day_1_en","features.messages.impl.actionlist_ActionListViewContent_Night_1_en",0,], -["features.messages.impl.actionlist_ActionListViewContent_Day_2_en","features.messages.impl.actionlist_ActionListViewContent_Night_2_en",20413,], -["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20413,], -["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20413,], -["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20413,], -["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20413,], -["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20413,], -["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20413,], -["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20413,], -["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20413,], -["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20413,], -["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20413,], -["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20413,], -["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20413,], -["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20413,], -["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20413,], +["features.messages.impl.actionlist_ActionListViewContent_Day_2_en","features.messages.impl.actionlist_ActionListViewContent_Night_2_en",20420,], +["features.messages.impl.actionlist_ActionListViewContent_Day_3_en","features.messages.impl.actionlist_ActionListViewContent_Night_3_en",20420,], +["features.messages.impl.actionlist_ActionListViewContent_Day_4_en","features.messages.impl.actionlist_ActionListViewContent_Night_4_en",20420,], +["features.messages.impl.actionlist_ActionListViewContent_Day_5_en","features.messages.impl.actionlist_ActionListViewContent_Night_5_en",20420,], +["features.messages.impl.actionlist_ActionListViewContent_Day_6_en","features.messages.impl.actionlist_ActionListViewContent_Night_6_en",20420,], +["features.messages.impl.actionlist_ActionListViewContent_Day_7_en","features.messages.impl.actionlist_ActionListViewContent_Night_7_en",20420,], +["features.messages.impl.actionlist_ActionListViewContent_Day_8_en","features.messages.impl.actionlist_ActionListViewContent_Night_8_en",20420,], +["features.messages.impl.actionlist_ActionListViewContent_Day_9_en","features.messages.impl.actionlist_ActionListViewContent_Night_9_en",20420,], +["features.createroom.impl.addpeople_AddPeopleView_Day_0_en","features.createroom.impl.addpeople_AddPeopleView_Night_0_en",20420,], +["features.createroom.impl.addpeople_AddPeopleView_Day_1_en","features.createroom.impl.addpeople_AddPeopleView_Night_1_en",20420,], +["features.createroom.impl.addpeople_AddPeopleView_Day_2_en","features.createroom.impl.addpeople_AddPeopleView_Night_2_en",20420,], +["features.createroom.impl.addpeople_AddPeopleView_Day_3_en","features.createroom.impl.addpeople_AddPeopleView_Night_3_en",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_0_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_1_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_2_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_3_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_4_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_5_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_6_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_7_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewDark_8_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_0_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_1_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_2_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_3_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_4_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_5_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_6_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_7_en","",20420,], +["features.preferences.impl.advanced_AdvancedSettingsViewLight_8_en","",20420,], +["libraries.designsystem.components.dialogs_AlertDialogContent_Dialogs_en","",20420,], +["libraries.designsystem.components.dialogs_AlertDialog_Day_0_en","libraries.designsystem.components.dialogs_AlertDialog_Night_0_en",20420,], ["libraries.designsystem.theme.components_AllIcons_Icons_en","",0,], -["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20413,], -["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20413,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20413,], -["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20413,], -["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20413,], +["features.analytics.impl_AnalyticsOptInView_Day_0_en","features.analytics.impl_AnalyticsOptInView_Night_0_en",20420,], +["features.analytics.impl_AnalyticsOptInView_Day_1_en","features.analytics.impl_AnalyticsOptInView_Night_1_en",20420,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_0_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_0_en",20420,], +["features.analytics.api.preferences_AnalyticsPreferencesView_Day_1_en","features.analytics.api.preferences_AnalyticsPreferencesView_Night_1_en",20420,], +["features.preferences.impl.analytics_AnalyticsSettingsView_Day_0_en","features.preferences.impl.analytics_AnalyticsSettingsView_Night_0_en",20420,], ["libraries.designsystem.components_Announcement_Day_0_en","libraries.designsystem.components_Announcement_Night_0_en",0,], -["services.apperror.impl_AppErrorView_Day_0_en","services.apperror.impl_AppErrorView_Night_0_en",20413,], +["services.apperror.impl_AppErrorView_Day_0_en","services.apperror.impl_AppErrorView_Night_0_en",20420,], ["libraries.designsystem.components.async_AsyncActionView_Day_0_en","libraries.designsystem.components.async_AsyncActionView_Night_0_en",0,], -["libraries.designsystem.components.async_AsyncActionView_Day_1_en","libraries.designsystem.components.async_AsyncActionView_Night_1_en",20413,], +["libraries.designsystem.components.async_AsyncActionView_Day_1_en","libraries.designsystem.components.async_AsyncActionView_Night_1_en",20420,], ["libraries.designsystem.components.async_AsyncActionView_Day_2_en","libraries.designsystem.components.async_AsyncActionView_Night_2_en",0,], -["libraries.designsystem.components.async_AsyncActionView_Day_3_en","libraries.designsystem.components.async_AsyncActionView_Night_3_en",20413,], +["libraries.designsystem.components.async_AsyncActionView_Day_3_en","libraries.designsystem.components.async_AsyncActionView_Night_3_en",20420,], ["libraries.designsystem.components.async_AsyncActionView_Day_4_en","libraries.designsystem.components.async_AsyncActionView_Night_4_en",0,], -["libraries.designsystem.components.async_AsyncFailure_Day_0_en","libraries.designsystem.components.async_AsyncFailure_Night_0_en",20413,], +["libraries.designsystem.components.async_AsyncFailure_Day_0_en","libraries.designsystem.components.async_AsyncFailure_Night_0_en",20420,], ["libraries.designsystem.components.async_AsyncIndicatorFailure_Day_0_en","libraries.designsystem.components.async_AsyncIndicatorFailure_Night_0_en",0,], ["libraries.designsystem.components.async_AsyncIndicatorLoading_Day_0_en","libraries.designsystem.components.async_AsyncIndicatorLoading_Night_0_en",0,], ["libraries.designsystem.components.async_AsyncLoading_Day_0_en","libraries.designsystem.components.async_AsyncLoading_Night_0_en",0,], -["features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en","features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en",20413,], +["features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Day_0_en","features.messages.impl.messagecomposer_AttachmentSourcePickerMenu_Night_0_en",20420,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_0_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_0_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_1_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_1_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_2_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_2_en",0,], @@ -84,19 +84,19 @@ export const screenshots = [ ["libraries.matrix.ui.components_AttachmentThumbnail_Day_6_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_6_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_7_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_7_en",0,], ["libraries.matrix.ui.components_AttachmentThumbnail_Day_8_en","libraries.matrix.ui.components_AttachmentThumbnail_Night_8_en",0,], -["features.messages.impl.attachments.preview_AttachmentsView_0_en","",20413,], -["features.messages.impl.attachments.preview_AttachmentsView_1_en","",20413,], -["features.messages.impl.attachments.preview_AttachmentsView_2_en","",20413,], -["features.messages.impl.attachments.preview_AttachmentsView_3_en","",20413,], -["features.messages.impl.attachments.preview_AttachmentsView_4_en","",20413,], -["features.messages.impl.attachments.preview_AttachmentsView_5_en","",20413,], -["features.messages.impl.attachments.preview_AttachmentsView_6_en","",20413,], -["features.messages.impl.attachments.preview_AttachmentsView_7_en","",20413,], -["features.messages.impl.attachments.preview_AttachmentsView_8_en","",20413,], +["features.messages.impl.attachments.preview_AttachmentsView_0_en","",20420,], +["features.messages.impl.attachments.preview_AttachmentsView_1_en","",20420,], +["features.messages.impl.attachments.preview_AttachmentsView_2_en","",20420,], +["features.messages.impl.attachments.preview_AttachmentsView_3_en","",20420,], +["features.messages.impl.attachments.preview_AttachmentsView_4_en","",20420,], +["features.messages.impl.attachments.preview_AttachmentsView_5_en","",20420,], +["features.messages.impl.attachments.preview_AttachmentsView_6_en","",20420,], +["features.messages.impl.attachments.preview_AttachmentsView_7_en","",20420,], +["features.messages.impl.attachments.preview_AttachmentsView_8_en","",20420,], ["libraries.mediaviewer.impl.gallery.ui_AudioItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_AudioItemView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_AudioItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_AudioItemView_Night_1_en",0,], ["libraries.mediaviewer.impl.gallery.ui_AudioItemView_Day_2_en","libraries.mediaviewer.impl.gallery.ui_AudioItemView_Night_2_en",0,], -["libraries.matrix.ui.components_AvatarActionBottomSheet_Day_0_en","libraries.matrix.ui.components_AvatarActionBottomSheet_Night_0_en",20413,], +["libraries.matrix.ui.components_AvatarActionBottomSheet_Day_0_en","libraries.matrix.ui.components_AvatarActionBottomSheet_Night_0_en",20420,], ["libraries.designsystem.components.avatar.internal_AvatarCluster_Avatars_en","",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_0_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_0_en",0,], ["libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Day_1_en","libraries.designsystem.components.avatar_AvatarRowLastOnTopRtl_Night_1_en",0,], @@ -123,22 +123,22 @@ export const screenshots = [ ["libraries.designsystem.modifiers_BackgroundVerticalGradientDisabled_Day_0_en","libraries.designsystem.modifiers_BackgroundVerticalGradientDisabled_Night_0_en",0,], ["libraries.designsystem.modifiers_BackgroundVerticalGradient_Day_0_en","libraries.designsystem.modifiers_BackgroundVerticalGradient_Night_0_en",0,], ["libraries.designsystem.components_Badge_Day_0_en","libraries.designsystem.components_Badge_Night_0_en",0,], -["features.home.impl.components_BatteryOptimizationBanner_Day_0_en","features.home.impl.components_BatteryOptimizationBanner_Night_0_en",20413,], +["features.home.impl.components_BatteryOptimizationBanner_Day_0_en","features.home.impl.components_BatteryOptimizationBanner_Night_0_en",20420,], ["libraries.designsystem.atomic.atoms_BetaLabel_Day_0_en","libraries.designsystem.atomic.atoms_BetaLabel_Night_0_en",0,], ["libraries.designsystem.components_BigIcon_Day_0_en","libraries.designsystem.components_BigIcon_Night_0_en",0,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en",20413,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20413,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20413,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20413,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20413,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20413,], -["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20413,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_0_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_0_en",20420,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_1_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_1_en",20420,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_2_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_2_en",20420,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_3_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_3_en",20420,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_4_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_4_en",20420,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_5_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_5_en",20420,], +["features.preferences.impl.blockedusers_BlockedUsersView_Day_6_en","features.preferences.impl.blockedusers_BlockedUsersView_Night_6_en",20420,], ["libraries.designsystem.theme.components_BottomSheetDragHandle_Day_0_en","libraries.designsystem.theme.components_BottomSheetDragHandle_Night_0_en",0,], -["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20413,], -["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20413,], -["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20413,], -["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20413,], -["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20413,], +["features.rageshake.impl.bugreport_BugReportViewDay_0_en","",20420,], +["features.rageshake.impl.bugreport_BugReportViewDay_1_en","",20420,], +["features.rageshake.impl.bugreport_BugReportViewDay_2_en","",20420,], +["features.rageshake.impl.bugreport_BugReportViewDay_3_en","",20420,], +["features.rageshake.impl.bugreport_BugReportViewDay_4_en","",20420,], ["features.rageshake.impl.bugreport_BugReportViewNight_0_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_1_en","",0,], ["features.rageshake.impl.bugreport_BugReportViewNight_2_en","",0,], @@ -148,133 +148,133 @@ export const screenshots = [ ["libraries.designsystem.atomic.molecules_ButtonRowMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ButtonRowMolecule_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_0_en","features.messages.impl.timeline.components_CallMenuItem_Night_0_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_1_en","features.messages.impl.timeline.components_CallMenuItem_Night_1_en",0,], -["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20413,], -["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20413,], +["features.messages.impl.timeline.components_CallMenuItem_Day_2_en","features.messages.impl.timeline.components_CallMenuItem_Night_2_en",20420,], +["features.messages.impl.timeline.components_CallMenuItem_Day_3_en","features.messages.impl.timeline.components_CallMenuItem_Night_3_en",20420,], ["features.messages.impl.timeline.components_CallMenuItem_Day_4_en","features.messages.impl.timeline.components_CallMenuItem_Night_4_en",0,], ["features.messages.impl.timeline.components_CallMenuItem_Day_5_en","features.messages.impl.timeline.components_CallMenuItem_Night_5_en",0,], ["features.call.impl.ui_CallScreenView_Day_0_en","features.call.impl.ui_CallScreenView_Night_0_en",0,], -["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20413,], -["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20413,], -["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20413,], -["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20413,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20413,], -["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20413,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20413,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20413,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20413,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20413,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20416,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20413,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20413,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20413,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20413,], +["features.call.impl.ui_CallScreenView_Day_1_en","features.call.impl.ui_CallScreenView_Night_1_en",20420,], +["features.call.impl.ui_CallScreenView_Day_2_en","features.call.impl.ui_CallScreenView_Night_2_en",20420,], +["features.call.impl.ui_CallScreenView_Day_3_en","features.call.impl.ui_CallScreenView_Night_3_en",20420,], +["libraries.textcomposer_CaptionWarningBottomSheet_Day_0_en","libraries.textcomposer_CaptionWarningBottomSheet_Night_0_en",20420,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_0_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_0_en",20420,], +["features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Day_1_en","features.login.impl.screens.changeaccountprovider_ChangeAccountProviderView_Night_1_en",20420,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_0_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_0_en",20420,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_10_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_10_en",20420,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_11_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_11_en",20420,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_12_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_12_en",20420,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_13_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_13_en",20420,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_1_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_1_en",20420,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_2_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_2_en",20420,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_3_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_3_en",20420,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_4_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_4_en",20420,], ["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_5_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_5_en",0,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en",20413,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20413,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20413,], -["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20413,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20413,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20413,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20413,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20413,], -["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20413,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_6_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_6_en",20420,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_7_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_7_en",20420,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_8_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_8_en",20420,], +["features.rolesandpermissions.impl.roles_ChangeRolesView_Day_9_en","features.rolesandpermissions.impl.roles_ChangeRolesView_Night_9_en",20420,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_0_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_0_en",20420,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_1_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_1_en",20420,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_2_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_2_en",20420,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_3_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_3_en",20420,], +["features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Day_4_en","features.rolesandpermissions.impl.permissions_ChangeRoomPermissionsView_Night_4_en",20420,], ["features.login.impl.changeserver_ChangeServerView_Day_0_en","features.login.impl.changeserver_ChangeServerView_Night_0_en",0,], -["features.login.impl.changeserver_ChangeServerView_Day_1_en","features.login.impl.changeserver_ChangeServerView_Night_1_en",20413,], -["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20413,], -["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20413,], -["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20413,], -["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20413,], +["features.login.impl.changeserver_ChangeServerView_Day_1_en","features.login.impl.changeserver_ChangeServerView_Night_1_en",20420,], +["features.login.impl.changeserver_ChangeServerView_Day_2_en","features.login.impl.changeserver_ChangeServerView_Night_2_en",20420,], +["features.login.impl.changeserver_ChangeServerView_Day_3_en","features.login.impl.changeserver_ChangeServerView_Night_3_en",20420,], +["features.login.impl.changeserver_ChangeServerView_Day_4_en","features.login.impl.changeserver_ChangeServerView_Night_4_en",20420,], +["features.login.impl.changeserver_ChangeServerView_Day_5_en","features.login.impl.changeserver_ChangeServerView_Night_5_en",20420,], ["libraries.matrix.ui.components_CheckableResolvedUserRow_en","",0,], -["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20413,], +["libraries.matrix.ui.components_CheckableUnresolvedUserRow_en","",20420,], ["libraries.designsystem.theme.components_Checkboxes_Toggles_en","",0,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_0_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_0_en",20413,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20413,], -["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20413,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20413,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20413,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20413,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20413,], -["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20413,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_0_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_0_en",20420,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_1_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_1_en",20420,], +["features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Day_2_en","features.login.impl.screens.chooseaccountprovider_ChooseAccountProviderView_Night_2_en",20420,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_0_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_0_en",20420,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_1_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_1_en",20420,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_2_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_2_en",20420,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_3_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_3_en",20420,], +["features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Day_4_en","features.ftue.impl.sessionverification.choosemode_ChooseSelfVerificationModeView_Night_4_en",20420,], ["libraries.designsystem.theme.components_CircularProgressIndicator_Progress_Indicators_en","",0,], ["libraries.designsystem.components_ClickableLinkText_Text_en","",0,], ["libraries.designsystem.theme_ColorAliases_Day_0_en","libraries.designsystem.theme_ColorAliases_Night_0_en",0,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_0_en",20413,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20413,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20413,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20413,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20413,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20413,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20413,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20413,], -["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20413,], -["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20413,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_0_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_0_en",20420,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_1_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_1_en",20420,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_2_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_2_en",20420,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_3_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_3_en",20420,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_4_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_4_en",20420,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_5_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_5_en",20420,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_6_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_6_en",20420,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_7_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_7_en",20420,], +["libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Day_8_en","libraries.designsystem.atomic.molecules_ComposerAlertMolecule_Night_8_en",20420,], +["libraries.textcomposer_ComposerModeView_Day_0_en","libraries.textcomposer_ComposerModeView_Night_0_en",20420,], ["libraries.textcomposer_ComposerModeView_Day_1_en","libraries.textcomposer_ComposerModeView_Night_1_en",0,], ["libraries.textcomposer_ComposerModeView_Day_2_en","libraries.textcomposer_ComposerModeView_Night_2_en",0,], ["libraries.textcomposer_ComposerModeView_Day_3_en","libraries.textcomposer_ComposerModeView_Night_3_en",0,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en","",20413,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20413,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20413,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20413,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20413,], -["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20413,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20413,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20413,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20413,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20413,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20413,], -["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20413,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20413,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20413,], -["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20413,], -["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20413,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_0_en","",20420,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_1_en","",20420,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_2_en","",20420,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_3_en","",20420,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_4_en","",20420,], +["features.createroom.impl.configureroom_ConfigureRoomViewDark_5_en","",20420,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_0_en","",20420,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_1_en","",20420,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_2_en","",20420,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_3_en","",20420,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_4_en","",20420,], +["features.createroom.impl.configureroom_ConfigureRoomViewLight_5_en","",20420,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_0_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_0_en",20420,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_1_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_1_en",20420,], +["features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Day_2_en","features.login.impl.screens.confirmaccountprovider_ConfirmAccountProviderView_Night_2_en",20420,], +["features.home.impl.components_ConfirmRecoveryKeyBanner_Day_0_en","features.home.impl.components_ConfirmRecoveryKeyBanner_Night_0_en",20420,], ["libraries.designsystem.components.dialogs_ConfirmationDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_ConfirmationDialog_Day_0_en","libraries.designsystem.components.dialogs_ConfirmationDialog_Night_0_en",0,], ["features.networkmonitor.api.ui_ConnectivityIndicator_Day_0_en","features.networkmonitor.api.ui_ConnectivityIndicator_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_CounterAtom_Day_0_en","libraries.designsystem.atomic.atoms_CounterAtom_Night_0_en",0,], -["features.rageshake.api.crash_CrashDetectionView_Day_0_en","features.rageshake.api.crash_CrashDetectionView_Night_0_en",20413,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20413,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20413,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20413,], -["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20413,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20413,], -["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20413,], -["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20413,], -["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20413,], -["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20413,], -["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20413,], -["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20413,], -["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20413,], -["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20413,], -["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20413,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20413,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20413,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20413,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20413,], -["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20413,], +["features.rageshake.api.crash_CrashDetectionView_Day_0_en","features.rageshake.api.crash_CrashDetectionView_Night_0_en",20420,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_0_en","features.login.impl.screens.createaccount_CreateAccountView_Night_0_en",20420,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_1_en","features.login.impl.screens.createaccount_CreateAccountView_Night_1_en",20420,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_2_en","features.login.impl.screens.createaccount_CreateAccountView_Night_2_en",20420,], +["features.login.impl.screens.createaccount_CreateAccountView_Day_3_en","features.login.impl.screens.createaccount_CreateAccountView_Night_3_en",20420,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_0_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_0_en",20420,], +["libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Day_1_en","libraries.matrix.ui.components_CreateDmConfirmationBottomSheet_Night_1_en",20420,], +["features.poll.impl.create_CreatePollView_Day_0_en","features.poll.impl.create_CreatePollView_Night_0_en",20420,], +["features.poll.impl.create_CreatePollView_Day_1_en","features.poll.impl.create_CreatePollView_Night_1_en",20420,], +["features.poll.impl.create_CreatePollView_Day_2_en","features.poll.impl.create_CreatePollView_Night_2_en",20420,], +["features.poll.impl.create_CreatePollView_Day_3_en","features.poll.impl.create_CreatePollView_Night_3_en",20420,], +["features.poll.impl.create_CreatePollView_Day_4_en","features.poll.impl.create_CreatePollView_Night_4_en",20420,], +["features.poll.impl.create_CreatePollView_Day_5_en","features.poll.impl.create_CreatePollView_Night_5_en",20420,], +["features.poll.impl.create_CreatePollView_Day_6_en","features.poll.impl.create_CreatePollView_Night_6_en",20420,], +["features.poll.impl.create_CreatePollView_Day_7_en","features.poll.impl.create_CreatePollView_Night_7_en",20420,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_0_en","",20420,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_1_en","",20420,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_2_en","",20420,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_3_en","",20420,], +["libraries.dateformatter.impl.previews_DateFormatterModeView_4_en","",20420,], ["libraries.mediaviewer.impl.gallery.ui_DateItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_DateItemView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_DateItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_DateItemView_Night_1_en",0,], -["libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_en","",20413,], -["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20413,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20413,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20413,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20413,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20413,], -["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20413,], +["libraries.designsystem.theme.components.previews_DatePickerDark_DateTime_pickers_en","",20420,], +["libraries.designsystem.theme.components.previews_DatePickerLight_DateTime_pickers_en","",20420,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_0_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_0_en",20420,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_1_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_1_en",20420,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_2_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_2_en",20420,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_3_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_3_en",20420,], +["features.invite.impl.declineandblock_DeclineAndBlockView_Day_4_en","features.invite.impl.declineandblock_DeclineAndBlockView_Night_4_en",20420,], ["features.logout.impl.direct_DefaultDirectLogoutView_Day_0_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_0_en",0,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_1_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_1_en",20413,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20413,], -["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20413,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_1_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_1_en",20420,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_2_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_2_en",20420,], +["features.logout.impl.direct_DefaultDirectLogoutView_Day_3_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_3_en",20420,], ["features.logout.impl.direct_DefaultDirectLogoutView_Day_4_en","features.logout.impl.direct_DefaultDirectLogoutView_Night_4_en",0,], -["features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Day_0_en","features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Night_0_en",20413,], +["features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Day_0_en","features.preferences.impl.notifications.edit_DefaultNotificationSettingOption_Night_0_en",20420,], ["features.licenses.impl.details_DependenciesDetailsView_Day_0_en","features.licenses.impl.details_DependenciesDetailsView_Night_0_en",0,], -["features.licenses.impl.list_DependencyLicensesListView_Day_0_en","features.licenses.impl.list_DependencyLicensesListView_Night_0_en",20413,], -["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20413,], -["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20413,], -["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20413,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20413,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20413,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20413,], -["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20413,], +["features.licenses.impl.list_DependencyLicensesListView_Day_0_en","features.licenses.impl.list_DependencyLicensesListView_Night_0_en",20420,], +["features.licenses.impl.list_DependencyLicensesListView_Day_1_en","features.licenses.impl.list_DependencyLicensesListView_Night_1_en",20420,], +["features.licenses.impl.list_DependencyLicensesListView_Day_2_en","features.licenses.impl.list_DependencyLicensesListView_Night_2_en",20420,], +["features.licenses.impl.list_DependencyLicensesListView_Day_3_en","features.licenses.impl.list_DependencyLicensesListView_Night_3_en",20420,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_0_en","features.preferences.impl.developer_DeveloperSettingsView_Night_0_en",20420,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_1_en","features.preferences.impl.developer_DeveloperSettingsView_Night_1_en",20420,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_2_en","features.preferences.impl.developer_DeveloperSettingsView_Night_2_en",20420,], +["features.preferences.impl.developer_DeveloperSettingsView_Day_3_en","features.preferences.impl.developer_DeveloperSettingsView_Night_3_en",20420,], ["libraries.designsystem.theme.components_DialogWithDestructiveButton_Dialog_with_destructive_button_Dialogs_en","",0,], ["libraries.designsystem.theme.components_DialogWithOnlyMessageAndOkButton_Dialog_with_only_message_and_ok_button_Dialogs_en","",0,], ["libraries.designsystem.theme.components_DialogWithThirdButton_Dialog_with_third_button_Dialogs_en","",0,], @@ -289,18 +289,19 @@ export const screenshots = [ ["libraries.designsystem.text_DpScale_1_0f__en","",0,], ["libraries.designsystem.text_DpScale_1_5f__en","",0,], ["libraries.designsystem.theme.components_DropdownMenuItem_Menus_en","",0,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_0_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_0_en",20413,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20413,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20413,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20413,], -["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20413,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_0_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_0_en",20413,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_1_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_1_en",20413,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_2_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_2_en",20413,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_3_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_3_en",20413,], -["features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Day_4_en","features.roomdetails.impl.securityandprivacy.editroomaddress_EditRoomAddressView_Night_4_en",20413,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20413,], -["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20413,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_0_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_0_en",20420,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_1_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_1_en",20420,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_2_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_2_en",20420,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_3_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_3_en",20420,], +["features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Day_4_en","features.preferences.impl.notifications.edit_EditDefaultNotificationSettingView_Night_4_en",20420,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_0_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_0_en",0,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_1_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_1_en",0,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_2_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_2_en",0,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_3_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_3_en",0,], +["features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Day_4_en","features.securityandprivacy.impl.editroomaddress_EditRoomAddressView_Night_4_en",0,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_0_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_0_en",20420,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_1_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_1_en",20420,], +["features.preferences.impl.user.editprofile_EditUserProfileView_Day_2_en","features.preferences.impl.user.editprofile_EditUserProfileView_Night_2_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_0_en","libraries.matrix.ui.components_EditableAvatarView_Night_0_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_1_en","libraries.matrix.ui.components_EditableAvatarView_Night_1_en",0,], ["libraries.matrix.ui.components_EditableAvatarView_Day_2_en","libraries.matrix.ui.components_EditableAvatarView_Night_2_en",0,], @@ -311,14 +312,14 @@ export const screenshots = [ ["libraries.designsystem.atomic.atoms_ElementLogoAtomMediumNoBlurShadow_Day_0_en","libraries.designsystem.atomic.atoms_ElementLogoAtomMediumNoBlurShadow_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_ElementLogoAtomMedium_Day_0_en","libraries.designsystem.atomic.atoms_ElementLogoAtomMedium_Night_0_en",0,], ["features.messages.impl.timeline.components.customreaction_EmojiItem_Day_0_en","features.messages.impl.timeline.components.customreaction_EmojiItem_Night_0_en",0,], -["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en",20413,], -["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20413,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_0_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_0_en",20420,], +["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_1_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_1_en",20420,], ["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_2_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_2_en",0,], ["features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Day_3_en","features.messages.impl.timeline.components.customreaction.picker_EmojiPicker_Night_3_en",0,], ["libraries.ui.common.nodes_EmptyView_Day_0_en","libraries.ui.common.nodes_EmptyView_Night_0_en",0,], -["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20413,], -["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20413,], -["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20413,], +["libraries.designsystem.components.dialogs_ErrorDialogContent_Dialogs_en","",20420,], +["libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialogWithDoNotShowAgain_Night_0_en",20420,], +["libraries.designsystem.components.dialogs_ErrorDialog_Day_0_en","libraries.designsystem.components.dialogs_ErrorDialog_Night_0_en",20420,], ["features.messages.impl.timeline.debug_EventDebugInfoView_Day_0_en","features.messages.impl.timeline.debug_EventDebugInfoView_Night_0_en",0,], ["libraries.designsystem.components_ExpandableBottomSheetLayout_en","",0,], ["libraries.featureflag.ui_FeatureListView_Day_0_en","libraries.featureflag.ui_FeatureListView_Night_0_en",0,], @@ -337,43 +338,43 @@ export const screenshots = [ ["libraries.designsystem.theme.components_FloatingActionButton_Floating_Action_Buttons_en","",0,], ["libraries.designsystem.atomic.pages_FlowStepPage_Day_0_en","libraries.designsystem.atomic.pages_FlowStepPage_Night_0_en",0,], ["features.messages.impl.timeline.focus_FocusRequestStateView_Day_0_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_0_en",0,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_1_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_1_en",20413,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20413,], -["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20413,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_1_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_1_en",20420,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_2_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_2_en",20420,], +["features.messages.impl.timeline.focus_FocusRequestStateView_Day_3_en","features.messages.impl.timeline.focus_FocusRequestStateView_Night_3_en",20420,], ["features.messages.impl.timeline.components_FocusedEvent_Day_0_en","features.messages.impl.timeline.components_FocusedEvent_Night_0_en",0,], ["libraries.textcomposer.components_FormattingOption_Day_0_en","libraries.textcomposer.components_FormattingOption_Night_0_en",0,], ["features.forward.impl_ForwardMessagesView_Day_0_en","features.forward.impl_ForwardMessagesView_Night_0_en",0,], ["features.forward.impl_ForwardMessagesView_Day_1_en","features.forward.impl_ForwardMessagesView_Night_1_en",0,], ["features.forward.impl_ForwardMessagesView_Day_2_en","features.forward.impl_ForwardMessagesView_Night_2_en",0,], -["features.forward.impl_ForwardMessagesView_Day_3_en","features.forward.impl_ForwardMessagesView_Night_3_en",20413,], -["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20413,], +["features.forward.impl_ForwardMessagesView_Day_3_en","features.forward.impl_ForwardMessagesView_Night_3_en",20420,], +["features.home.impl.components_FullScreenIntentPermissionBanner_Day_0_en","features.home.impl.components_FullScreenIntentPermissionBanner_Night_0_en",20420,], ["libraries.designsystem.components.button_GradientFloatingActionButtonCircleShape_Day_0_en","libraries.designsystem.components.button_GradientFloatingActionButtonCircleShape_Night_0_en",0,], ["libraries.designsystem.components.button_GradientFloatingActionButton_Day_0_en","libraries.designsystem.components.button_GradientFloatingActionButton_Night_0_en",0,], ["features.messages.impl.timeline.components.group_GroupHeaderView_Day_0_en","features.messages.impl.timeline.components.group_GroupHeaderView_Night_0_en",0,], ["libraries.designsystem.atomic.pages_HeaderFooterPageScrollable_Day_0_en","libraries.designsystem.atomic.pages_HeaderFooterPageScrollable_Night_0_en",0,], ["libraries.designsystem.atomic.pages_HeaderFooterPage_Day_0_en","libraries.designsystem.atomic.pages_HeaderFooterPage_Night_0_en",0,], -["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20413,], -["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20413,], -["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20413,], -["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20413,], -["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20413,], +["features.home.impl.spaces_HomeSpacesView_Day_0_en","features.home.impl.spaces_HomeSpacesView_Night_0_en",20420,], +["features.home.impl.spaces_HomeSpacesView_Day_1_en","features.home.impl.spaces_HomeSpacesView_Night_1_en",20420,], +["features.home.impl.components_HomeTopBarMultiAccount_Day_0_en","features.home.impl.components_HomeTopBarMultiAccount_Night_0_en",20420,], +["features.home.impl.components_HomeTopBarWithIndicator_Day_0_en","features.home.impl.components_HomeTopBarWithIndicator_Night_0_en",20420,], +["features.home.impl.components_HomeTopBar_Day_0_en","features.home.impl.components_HomeTopBar_Night_0_en",20420,], ["features.home.impl_HomeViewA11y_en","",0,], -["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20413,], -["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20413,], +["features.home.impl_HomeView_Day_0_en","features.home.impl_HomeView_Night_0_en",20420,], +["features.home.impl_HomeView_Day_10_en","features.home.impl_HomeView_Night_10_en",20420,], ["features.home.impl_HomeView_Day_11_en","features.home.impl_HomeView_Night_11_en",0,], ["features.home.impl_HomeView_Day_12_en","features.home.impl_HomeView_Night_12_en",0,], -["features.home.impl_HomeView_Day_13_en","features.home.impl_HomeView_Night_13_en",20413,], -["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20413,], -["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20413,], -["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20413,], -["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20413,], -["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20413,], -["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20413,], -["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20413,], -["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20413,], -["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20413,], -["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20413,], -["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20413,], +["features.home.impl_HomeView_Day_13_en","features.home.impl_HomeView_Night_13_en",20420,], +["features.home.impl_HomeView_Day_14_en","features.home.impl_HomeView_Night_14_en",20420,], +["features.home.impl_HomeView_Day_15_en","features.home.impl_HomeView_Night_15_en",20420,], +["features.home.impl_HomeView_Day_1_en","features.home.impl_HomeView_Night_1_en",20420,], +["features.home.impl_HomeView_Day_2_en","features.home.impl_HomeView_Night_2_en",20420,], +["features.home.impl_HomeView_Day_3_en","features.home.impl_HomeView_Night_3_en",20420,], +["features.home.impl_HomeView_Day_4_en","features.home.impl_HomeView_Night_4_en",20420,], +["features.home.impl_HomeView_Day_5_en","features.home.impl_HomeView_Night_5_en",20420,], +["features.home.impl_HomeView_Day_6_en","features.home.impl_HomeView_Night_6_en",20420,], +["features.home.impl_HomeView_Day_7_en","features.home.impl_HomeView_Night_7_en",20420,], +["features.home.impl_HomeView_Day_8_en","features.home.impl_HomeView_Night_8_en",20420,], +["features.home.impl_HomeView_Day_9_en","features.home.impl_HomeView_Night_9_en",20420,], ["libraries.designsystem.theme.components_HorizontalDivider_Dividers_en","",0,], ["libraries.designsystem.ruler_HorizontalRuler_Day_0_en","libraries.designsystem.ruler_HorizontalRuler_Night_0_en",0,], ["libraries.designsystem.theme.components_IconButton_Buttons_en","",0,], @@ -386,8 +387,8 @@ export const screenshots = [ ["appicon.enterprise_Icon_en","",0,], ["libraries.designsystem.icons_IconsOther_Day_0_en","libraries.designsystem.icons_IconsOther_Night_0_en",0,], ["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_0_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_0_en",0,], -["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_1_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_1_en",20413,], -["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20413,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_1_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_1_en",20420,], +["features.messages.impl.crypto.identity_IdentityChangeStateView_Day_2_en","features.messages.impl.crypto.identity_IdentityChangeStateView_Night_2_en",20420,], ["libraries.mediaviewer.impl.gallery.ui_ImageItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_ImageItemView_Night_0_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_0_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_0_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_10_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_10_en",0,], @@ -395,109 +396,109 @@ export const screenshots = [ ["libraries.matrix.ui.messages.reply_InReplyToView_Day_1_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_1_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_2_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_2_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_3_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_3_en",0,], -["libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en",20413,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_4_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_4_en",20420,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_5_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_5_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_6_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_6_en",0,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_7_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_7_en",0,], -["libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en",20413,], +["libraries.matrix.ui.messages.reply_InReplyToView_Day_8_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_8_en",20420,], ["libraries.matrix.ui.messages.reply_InReplyToView_Day_9_en","libraries.matrix.ui.messages.reply_InReplyToView_Night_9_en",0,], -["features.call.impl.ui_IncomingCallScreen_Day_0_en","features.call.impl.ui_IncomingCallScreen_Night_0_en",20413,], +["features.call.impl.ui_IncomingCallScreen_Day_0_en","features.call.impl.ui_IncomingCallScreen_Night_0_en",20420,], ["features.verifysession.impl.incoming_IncomingVerificationViewA11y_en","",0,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20413,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20413,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20413,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20413,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20413,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20413,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20413,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20413,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20413,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20413,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20413,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20413,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20413,], -["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20413,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_0_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_0_en",20420,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_10_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_10_en",20420,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_11_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_11_en",20420,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_12_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_12_en",20420,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_13_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_13_en",20420,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_1_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_1_en",20420,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_2_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_2_en",20420,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_3_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_3_en",20420,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_4_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_4_en",20420,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_5_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_5_en",20420,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_6_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_6_en",20420,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_7_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_7_en",20420,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_8_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_8_en",20420,], +["features.verifysession.impl.incoming_IncomingVerificationView_Day_9_en","features.verifysession.impl.incoming_IncomingVerificationView_Night_9_en",20420,], ["libraries.designsystem.atomic.molecules_InfoListItemMolecule_Day_0_en","libraries.designsystem.atomic.molecules_InfoListItemMolecule_Night_0_en",0,], ["libraries.designsystem.atomic.organisms_InfoListOrganism_Day_0_en","libraries.designsystem.atomic.organisms_InfoListOrganism_Night_0_en",0,], ["libraries.matrix.ui.media_InitialsAvatarBitmapGenerator_Day_0_en","libraries.matrix.ui.media_InitialsAvatarBitmapGenerator_Night_0_en",0,], -["features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en","features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en",20413,], -["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20413,], -["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20413,], +["features.call.impl.ui_InvalidAudioDeviceDialog_Day_0_en","features.call.impl.ui_InvalidAudioDeviceDialog_Night_0_en",20420,], +["features.invitepeople.impl_InvitePeopleView_Day_0_en","features.invitepeople.impl_InvitePeopleView_Night_0_en",20420,], +["features.invitepeople.impl_InvitePeopleView_Day_1_en","features.invitepeople.impl_InvitePeopleView_Night_1_en",20420,], ["features.invitepeople.impl_InvitePeopleView_Day_2_en","features.invitepeople.impl_InvitePeopleView_Night_2_en",0,], ["features.invitepeople.impl_InvitePeopleView_Day_3_en","features.invitepeople.impl_InvitePeopleView_Night_3_en",0,], -["features.invitepeople.impl_InvitePeopleView_Day_4_en","features.invitepeople.impl_InvitePeopleView_Night_4_en",20413,], -["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20413,], -["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20413,], -["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20413,], +["features.invitepeople.impl_InvitePeopleView_Day_4_en","features.invitepeople.impl_InvitePeopleView_Night_4_en",20420,], +["features.invitepeople.impl_InvitePeopleView_Day_5_en","features.invitepeople.impl_InvitePeopleView_Night_5_en",20420,], +["features.invitepeople.impl_InvitePeopleView_Day_6_en","features.invitepeople.impl_InvitePeopleView_Night_6_en",20420,], +["features.invitepeople.impl_InvitePeopleView_Day_7_en","features.invitepeople.impl_InvitePeopleView_Night_7_en",20420,], ["features.invitepeople.impl_InvitePeopleView_Day_8_en","features.invitepeople.impl_InvitePeopleView_Night_8_en",0,], -["features.invitepeople.impl_InvitePeopleView_Day_9_en","features.invitepeople.impl_InvitePeopleView_Night_9_en",20413,], -["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20413,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20413,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20413,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20413,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20413,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20413,], -["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20413,], +["features.invitepeople.impl_InvitePeopleView_Day_9_en","features.invitepeople.impl_InvitePeopleView_Night_9_en",20420,], +["libraries.matrix.ui.components_InviteSenderView_Day_0_en","libraries.matrix.ui.components_InviteSenderView_Night_0_en",20420,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_0_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_0_en",20420,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_1_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_1_en",20420,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_2_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_2_en",20420,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_3_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_3_en",20420,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_4_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_4_en",20420,], +["features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Day_5_en","features.startchat.impl.joinbyaddress_JoinRoomByAddressView_Night_5_en",20420,], ["features.joinroom.impl_JoinRoomView_Day_0_en","features.joinroom.impl_JoinRoomView_Night_0_en",0,], -["features.joinroom.impl_JoinRoomView_Day_10_en","features.joinroom.impl_JoinRoomView_Night_10_en",20413,], -["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20413,], -["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20413,], -["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20413,], -["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20413,], -["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20413,], -["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20413,], -["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20413,], -["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20413,], -["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20413,], -["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20413,], -["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20413,], -["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20413,], -["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20413,], -["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20413,], -["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20413,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20413,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20413,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20413,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20413,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20413,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20413,], -["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20413,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20413,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20413,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20413,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20413,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20413,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20413,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20413,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20413,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20413,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20413,], -["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20413,], +["features.joinroom.impl_JoinRoomView_Day_10_en","features.joinroom.impl_JoinRoomView_Night_10_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_11_en","features.joinroom.impl_JoinRoomView_Night_11_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_12_en","features.joinroom.impl_JoinRoomView_Night_12_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_13_en","features.joinroom.impl_JoinRoomView_Night_13_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_14_en","features.joinroom.impl_JoinRoomView_Night_14_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_15_en","features.joinroom.impl_JoinRoomView_Night_15_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_16_en","features.joinroom.impl_JoinRoomView_Night_16_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_1_en","features.joinroom.impl_JoinRoomView_Night_1_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_2_en","features.joinroom.impl_JoinRoomView_Night_2_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_3_en","features.joinroom.impl_JoinRoomView_Night_3_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_4_en","features.joinroom.impl_JoinRoomView_Night_4_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_5_en","features.joinroom.impl_JoinRoomView_Night_5_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_6_en","features.joinroom.impl_JoinRoomView_Night_6_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_7_en","features.joinroom.impl_JoinRoomView_Night_7_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_8_en","features.joinroom.impl_JoinRoomView_Night_8_en",20420,], +["features.joinroom.impl_JoinRoomView_Day_9_en","features.joinroom.impl_JoinRoomView_Night_9_en",20420,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_0_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_0_en",20420,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_1_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_1_en",20420,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_2_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_2_en",20420,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_3_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_3_en",20420,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_4_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_4_en",20420,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_5_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_5_en",20420,], +["features.knockrequests.impl.banner_KnockRequestsBannerView_Day_6_en","features.knockrequests.impl.banner_KnockRequestsBannerView_Night_6_en",20420,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_0_en","features.knockrequests.impl.list_KnockRequestsListView_Night_0_en",20420,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_10_en","features.knockrequests.impl.list_KnockRequestsListView_Night_10_en",20420,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_1_en","features.knockrequests.impl.list_KnockRequestsListView_Night_1_en",20420,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_2_en","features.knockrequests.impl.list_KnockRequestsListView_Night_2_en",20420,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_3_en","features.knockrequests.impl.list_KnockRequestsListView_Night_3_en",20420,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_4_en","features.knockrequests.impl.list_KnockRequestsListView_Night_4_en",20420,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_5_en","features.knockrequests.impl.list_KnockRequestsListView_Night_5_en",20420,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_6_en","features.knockrequests.impl.list_KnockRequestsListView_Night_6_en",20420,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_7_en","features.knockrequests.impl.list_KnockRequestsListView_Night_7_en",20420,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_8_en","features.knockrequests.impl.list_KnockRequestsListView_Night_8_en",20420,], +["features.knockrequests.impl.list_KnockRequestsListView_Day_9_en","features.knockrequests.impl.list_KnockRequestsListView_Night_9_en",20420,], ["libraries.designsystem.components_LabelledCheckbox_Toggles_en","",0,], -["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20413,], -["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20413,], +["features.preferences.impl.labs_LabsView_Day_0_en","features.preferences.impl.labs_LabsView_Night_0_en",20420,], +["features.preferences.impl.labs_LabsView_Day_1_en","features.preferences.impl.labs_LabsView_Night_1_en",20420,], ["features.leaveroom.impl_LeaveRoomView_Day_0_en","features.leaveroom.impl_LeaveRoomView_Night_0_en",0,], -["features.leaveroom.impl_LeaveRoomView_Day_1_en","features.leaveroom.impl_LeaveRoomView_Night_1_en",20413,], -["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20413,], -["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20413,], -["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20413,], -["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20413,], -["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20413,], -["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20413,], -["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20413,], -["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20413,], -["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20413,], -["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20413,], -["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20413,], -["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20413,], -["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20413,], -["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20413,], -["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20413,], -["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20413,], +["features.leaveroom.impl_LeaveRoomView_Day_1_en","features.leaveroom.impl_LeaveRoomView_Night_1_en",20420,], +["features.leaveroom.impl_LeaveRoomView_Day_2_en","features.leaveroom.impl_LeaveRoomView_Night_2_en",20420,], +["features.leaveroom.impl_LeaveRoomView_Day_3_en","features.leaveroom.impl_LeaveRoomView_Night_3_en",20420,], +["features.leaveroom.impl_LeaveRoomView_Day_4_en","features.leaveroom.impl_LeaveRoomView_Night_4_en",20420,], +["features.leaveroom.impl_LeaveRoomView_Day_5_en","features.leaveroom.impl_LeaveRoomView_Night_5_en",20420,], +["features.leaveroom.impl_LeaveRoomView_Day_6_en","features.leaveroom.impl_LeaveRoomView_Night_6_en",20420,], +["features.leaveroom.impl_LeaveRoomView_Day_7_en","features.leaveroom.impl_LeaveRoomView_Night_7_en",20420,], +["features.space.impl.leave_LeaveSpaceView_Day_0_en","features.space.impl.leave_LeaveSpaceView_Night_0_en",20420,], +["features.space.impl.leave_LeaveSpaceView_Day_1_en","features.space.impl.leave_LeaveSpaceView_Night_1_en",20420,], +["features.space.impl.leave_LeaveSpaceView_Day_2_en","features.space.impl.leave_LeaveSpaceView_Night_2_en",20420,], +["features.space.impl.leave_LeaveSpaceView_Day_3_en","features.space.impl.leave_LeaveSpaceView_Night_3_en",20420,], +["features.space.impl.leave_LeaveSpaceView_Day_4_en","features.space.impl.leave_LeaveSpaceView_Night_4_en",20420,], +["features.space.impl.leave_LeaveSpaceView_Day_5_en","features.space.impl.leave_LeaveSpaceView_Night_5_en",20420,], +["features.space.impl.leave_LeaveSpaceView_Day_6_en","features.space.impl.leave_LeaveSpaceView_Night_6_en",20420,], +["features.space.impl.leave_LeaveSpaceView_Day_7_en","features.space.impl.leave_LeaveSpaceView_Night_7_en",20420,], +["features.space.impl.leave_LeaveSpaceView_Day_8_en","features.space.impl.leave_LeaveSpaceView_Night_8_en",20420,], +["features.space.impl.leave_LeaveSpaceView_Day_9_en","features.space.impl.leave_LeaveSpaceView_Night_9_en",20420,], ["libraries.designsystem.background_LightGradientBackground_Day_0_en","libraries.designsystem.background_LightGradientBackground_Night_0_en",0,], ["libraries.designsystem.theme.components_LinearProgressIndicator_Progress_Indicators_en","",0,], ["features.messages.impl.link_LinkView_Day_0_en","features.messages.impl.link_LinkView_Night_0_en",0,], -["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20413,], +["features.messages.impl.link_LinkView_Day_1_en","features.messages.impl.link_LinkView_Night_1_en",20420,], ["libraries.designsystem.components.dialogs_ListDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_ListDialog_Day_0_en","libraries.designsystem.components.dialogs_ListDialog_Night_0_en",0,], ["libraries.designsystem.theme.components_ListItemPrimaryActionWithIcon_List_item_-_Primary_action_&_Icon_List_items_en","",0,], @@ -552,38 +553,38 @@ export const screenshots = [ ["libraries.designsystem.theme.components_ListSupportingTextSmallPadding_List_supporting_text_-_small_padding_List_sections_en","",0,], ["libraries.textcomposer.components_LiveWaveformView_Day_0_en","libraries.textcomposer.components_LiveWaveformView_Night_0_en",0,], ["appnav.room.joined_LoadingRoomNodeView_Day_0_en","appnav.room.joined_LoadingRoomNodeView_Night_0_en",0,], -["appnav.room.joined_LoadingRoomNodeView_Day_1_en","appnav.room.joined_LoadingRoomNodeView_Night_1_en",20413,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20413,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20413,], -["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20413,], +["appnav.room.joined_LoadingRoomNodeView_Day_1_en","appnav.room.joined_LoadingRoomNodeView_Night_1_en",20420,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_0_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_0_en",20420,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_1_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_1_en",20420,], +["features.lockscreen.impl.settings_LockScreenSettingsView_Day_2_en","features.lockscreen.impl.settings_LockScreenSettingsView_Night_2_en",20420,], ["appnav.loggedin_LoggedInView_Day_0_en","appnav.loggedin_LoggedInView_Night_0_en",0,], -["appnav.loggedin_LoggedInView_Day_1_en","appnav.loggedin_LoggedInView_Night_1_en",20413,], -["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20413,], -["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20413,], -["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20413,], -["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20413,], -["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20413,], -["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20413,], -["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20413,], -["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20413,], -["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20413,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20413,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20413,], -["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20413,], -["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20413,], -["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20413,], -["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20413,], -["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20413,], -["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20413,], -["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20413,], -["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20413,], -["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20413,], -["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20413,], -["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20413,], -["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20413,], -["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20413,], +["appnav.loggedin_LoggedInView_Day_1_en","appnav.loggedin_LoggedInView_Night_1_en",20420,], +["appnav.loggedin_LoggedInView_Day_2_en","appnav.loggedin_LoggedInView_Night_2_en",20420,], +["appnav.loggedin_LoggedInView_Day_3_en","appnav.loggedin_LoggedInView_Night_3_en",20420,], +["features.login.impl.login_LoginModeView_Day_0_en","features.login.impl.login_LoginModeView_Night_0_en",20420,], +["features.login.impl.login_LoginModeView_Day_1_en","features.login.impl.login_LoginModeView_Night_1_en",20420,], +["features.login.impl.login_LoginModeView_Day_2_en","features.login.impl.login_LoginModeView_Night_2_en",20420,], +["features.login.impl.login_LoginModeView_Day_3_en","features.login.impl.login_LoginModeView_Night_3_en",20420,], +["features.login.impl.login_LoginModeView_Day_4_en","features.login.impl.login_LoginModeView_Night_4_en",20420,], +["features.login.impl.login_LoginModeView_Day_5_en","features.login.impl.login_LoginModeView_Night_5_en",20420,], +["features.login.impl.login_LoginModeView_Day_6_en","features.login.impl.login_LoginModeView_Night_6_en",20420,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_0_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_0_en",20420,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_1_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_1_en",20420,], +["features.login.impl.screens.loginpassword_LoginPasswordView_Day_2_en","features.login.impl.screens.loginpassword_LoginPasswordView_Night_2_en",20420,], +["features.logout.impl_LogoutView_Day_0_en","features.logout.impl_LogoutView_Night_0_en",20420,], +["features.logout.impl_LogoutView_Day_10_en","features.logout.impl_LogoutView_Night_10_en",20420,], +["features.logout.impl_LogoutView_Day_11_en","features.logout.impl_LogoutView_Night_11_en",20420,], +["features.logout.impl_LogoutView_Day_1_en","features.logout.impl_LogoutView_Night_1_en",20420,], +["features.logout.impl_LogoutView_Day_2_en","features.logout.impl_LogoutView_Night_2_en",20420,], +["features.logout.impl_LogoutView_Day_3_en","features.logout.impl_LogoutView_Night_3_en",20420,], +["features.logout.impl_LogoutView_Day_4_en","features.logout.impl_LogoutView_Night_4_en",20420,], +["features.logout.impl_LogoutView_Day_5_en","features.logout.impl_LogoutView_Night_5_en",20420,], +["features.logout.impl_LogoutView_Day_6_en","features.logout.impl_LogoutView_Night_6_en",20420,], +["features.logout.impl_LogoutView_Day_7_en","features.logout.impl_LogoutView_Night_7_en",20420,], +["features.logout.impl_LogoutView_Day_8_en","features.logout.impl_LogoutView_Night_8_en",20420,], +["features.logout.impl_LogoutView_Day_9_en","features.logout.impl_LogoutView_Night_9_en",20420,], ["libraries.designsystem.components.button_MainActionButton_Buttons_en","",0,], -["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20413,], +["libraries.textcomposer_MarkdownTextComposerEdit_Day_0_en","libraries.textcomposer_MarkdownTextComposerEdit_Night_0_en",20420,], ["libraries.textcomposer.components.markdown_MarkdownTextInput_Day_0_en","libraries.textcomposer.components.markdown_MarkdownTextInput_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_MatrixBadgeAtomInfo_Day_0_en","libraries.designsystem.atomic.atoms_MatrixBadgeAtomInfo_Night_0_en",0,], ["libraries.designsystem.atomic.atoms_MatrixBadgeAtomNegative_Day_0_en","libraries.designsystem.atomic.atoms_MatrixBadgeAtomNegative_Night_0_en",0,], @@ -596,22 +597,22 @@ export const screenshots = [ ["libraries.matrix.ui.components_MatrixUserRow_Day_1_en","libraries.matrix.ui.components_MatrixUserRow_Night_1_en",0,], ["libraries.mediaviewer.impl.local.audio_MediaAudioView_Day_0_en","libraries.mediaviewer.impl.local.audio_MediaAudioView_Night_0_en",0,], ["libraries.mediaviewer.impl.local.audio_MediaAudioView_Day_1_en","libraries.mediaviewer.impl.local.audio_MediaAudioView_Night_1_en",0,], -["libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Night_0_en",20413,], -["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20413,], +["libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDeleteConfirmationBottomSheet_Night_0_en",20420,], +["libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Day_0_en","libraries.mediaviewer.impl.details_MediaDetailsBottomSheet_Night_0_en",20420,], ["libraries.mediaviewer.impl.local.file_MediaFileView_Day_0_en","libraries.mediaviewer.impl.local.file_MediaFileView_Night_0_en",0,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_0_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_0_en",20413,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20413,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20413,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20413,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20413,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20413,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20413,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20413,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20413,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20413,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20413,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20413,], -["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20413,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_0_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_0_en",20420,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_10_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_10_en",20420,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_11_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_11_en",20420,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_12_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_12_en",20420,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_1_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_1_en",20420,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_2_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_2_en",20420,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_3_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_3_en",20420,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_4_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_4_en",20420,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_5_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_5_en",20420,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_6_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_6_en",20420,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_7_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_7_en",20420,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_8_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_8_en",20420,], +["libraries.mediaviewer.impl.gallery_MediaGalleryView_Day_9_en","libraries.mediaviewer.impl.gallery_MediaGalleryView_Night_9_en",20420,], ["libraries.mediaviewer.impl.local.image_MediaImageView_Day_0_en","libraries.mediaviewer.impl.local.image_MediaImageView_Night_0_en",0,], ["libraries.mediaviewer.impl.local.player_MediaPlayerControllerView_Day_0_en","libraries.mediaviewer.impl.local.player_MediaPlayerControllerView_Night_0_en",0,], ["libraries.mediaviewer.impl.local.player_MediaPlayerControllerView_Day_1_en","libraries.mediaviewer.impl.local.player_MediaPlayerControllerView_Night_1_en",0,], @@ -619,14 +620,14 @@ export const screenshots = [ ["libraries.mediaviewer.impl.local.video_MediaVideoView_Day_0_en","libraries.mediaviewer.impl.local.video_MediaVideoView_Night_0_en",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_0_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_10_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_11_en","",20413,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20413,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_11_en","",20420,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_12_en","",20420,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_13_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20413,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_14_en","",20420,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_15_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_16_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_1_en","",0,], -["libraries.mediaviewer.impl.viewer_MediaViewerView_2_en","",20413,], +["libraries.mediaviewer.impl.viewer_MediaViewerView_2_en","",20420,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_3_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_4_en","",0,], ["libraries.mediaviewer.impl.viewer_MediaViewerView_5_en","",0,], @@ -640,7 +641,7 @@ export const screenshots = [ ["libraries.textcomposer.mentions_MentionSpanTheme_Day_0_en","libraries.textcomposer.mentions_MentionSpanTheme_Night_0_en",0,], ["libraries.designsystem.theme.components.previews_Menu_Menus_en","",0,], ["features.messages.impl.messagecomposer_MessageComposerViewVoice_Day_0_en","features.messages.impl.messagecomposer_MessageComposerViewVoice_Night_0_en",0,], -["features.messages.impl.messagecomposer_MessageComposerView_Day_0_en","features.messages.impl.messagecomposer_MessageComposerView_Night_0_en",20413,], +["features.messages.impl.messagecomposer_MessageComposerView_Day_0_en","features.messages.impl.messagecomposer_MessageComposerView_Night_0_en",20420,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_0_en","features.messages.impl.timeline.components_MessageEventBubble_Night_0_en",0,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_1_en","features.messages.impl.timeline.components_MessageEventBubble_Night_1_en",0,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_2_en","features.messages.impl.timeline.components_MessageEventBubble_Night_2_en",0,], @@ -649,7 +650,7 @@ export const screenshots = [ ["features.messages.impl.timeline.components_MessageEventBubble_Day_5_en","features.messages.impl.timeline.components_MessageEventBubble_Night_5_en",0,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_6_en","features.messages.impl.timeline.components_MessageEventBubble_Night_6_en",0,], ["features.messages.impl.timeline.components_MessageEventBubble_Day_7_en","features.messages.impl.timeline.components_MessageEventBubble_Night_7_en",0,], -["features.messages.impl.timeline.components_MessageShieldView_Day_0_en","features.messages.impl.timeline.components_MessageShieldView_Night_0_en",20413,], +["features.messages.impl.timeline.components_MessageShieldView_Day_0_en","features.messages.impl.timeline.components_MessageShieldView_Night_0_en",20420,], ["features.messages.impl.timeline.components_MessageStateEventContainer_Day_0_en","features.messages.impl.timeline.components_MessageStateEventContainer_Night_0_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButtonAdd_Day_0_en","features.messages.impl.timeline.components_MessagesReactionButtonAdd_Night_0_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButtonExtra_Day_0_en","features.messages.impl.timeline.components_MessagesReactionButtonExtra_Night_0_en",0,], @@ -657,137 +658,137 @@ export const screenshots = [ ["features.messages.impl.timeline.components_MessagesReactionButton_Day_1_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_1_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_2_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_2_en",0,], ["features.messages.impl.timeline.components_MessagesReactionButton_Day_3_en","features.messages.impl.timeline.components_MessagesReactionButton_Night_3_en",0,], -["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20413,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20413,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20413,], -["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20413,], -["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20413,], -["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20413,], -["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20413,], -["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20413,], -["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20413,], -["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20413,], -["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20413,], -["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20413,], -["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20413,], -["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20413,], +["features.messages.impl.topbars_MessagesViewTopBar_Day_0_en","features.messages.impl.topbars_MessagesViewTopBar_Night_0_en",20420,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_0_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_0_en",20420,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_1_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_1_en",20420,], +["features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Day_2_en","features.messages.impl.crypto.identity_MessagesViewWithIdentityChange_Night_2_en",20420,], +["features.messages.impl_MessagesView_Day_0_en","features.messages.impl_MessagesView_Night_0_en",20420,], +["features.messages.impl_MessagesView_Day_1_en","features.messages.impl_MessagesView_Night_1_en",20420,], +["features.messages.impl_MessagesView_Day_2_en","features.messages.impl_MessagesView_Night_2_en",20420,], +["features.messages.impl_MessagesView_Day_3_en","features.messages.impl_MessagesView_Night_3_en",20420,], +["features.messages.impl_MessagesView_Day_4_en","features.messages.impl_MessagesView_Night_4_en",20420,], +["features.messages.impl_MessagesView_Day_5_en","features.messages.impl_MessagesView_Night_5_en",20420,], +["features.messages.impl_MessagesView_Day_6_en","features.messages.impl_MessagesView_Night_6_en",20420,], +["features.messages.impl_MessagesView_Day_7_en","features.messages.impl_MessagesView_Night_7_en",20420,], +["features.messages.impl_MessagesView_Day_8_en","features.messages.impl_MessagesView_Night_8_en",20420,], +["features.messages.impl_MessagesView_Day_9_en","features.messages.impl_MessagesView_Night_9_en",20420,], ["features.migration.impl_MigrationView_Day_0_en","features.migration.impl_MigrationView_Night_0_en",0,], -["features.migration.impl_MigrationView_Day_1_en","features.migration.impl_MigrationView_Night_1_en",20413,], +["features.migration.impl_MigrationView_Day_1_en","features.migration.impl_MigrationView_Night_1_en",20420,], ["libraries.designsystem.theme.components_ModalBottomSheetDark_Bottom_Sheets_en","",0,], ["libraries.designsystem.theme.components_ModalBottomSheetLight_Bottom_Sheets_en","",0,], ["appicon.element_MonochromeIcon_en","",0,], -["features.preferences.impl.root_MultiAccountSection_Day_0_en","features.preferences.impl.root_MultiAccountSection_Night_0_en",20413,], +["features.preferences.impl.root_MultiAccountSection_Day_0_en","features.preferences.impl.root_MultiAccountSection_Night_0_en",20420,], ["libraries.designsystem.components.dialogs_MultipleSelectionDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_MultipleSelectionDialog_Day_0_en","libraries.designsystem.components.dialogs_MultipleSelectionDialog_Night_0_en",0,], ["libraries.designsystem.components.list_MutipleSelectionListItemSelectedTrailingContent_Multiple_selection_List_item_-_selection_in_trailing_content_List_items_en","",0,], ["libraries.designsystem.components.list_MutipleSelectionListItemSelected_Multiple_selection_List_item_-_selection_in_supporting_text_List_items_en","",0,], ["libraries.designsystem.components.list_MutipleSelectionListItem_Multiple_selection_List_item_-_no_selection_List_items_en","",0,], ["libraries.designsystem.theme.components_NavigationBar_App_Bars_en","",0,], -["features.home.impl.components_NewNotificationSoundBanner_Day_0_en","features.home.impl.components_NewNotificationSoundBanner_Night_0_en",20413,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20413,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20413,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20413,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20413,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20413,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20413,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20413,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20413,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20413,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20413,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20413,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20413,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20413,], -["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20413,], -["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20413,], +["features.home.impl.components_NewNotificationSoundBanner_Day_0_en","features.home.impl.components_NewNotificationSoundBanner_Night_0_en",20420,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_0_en","features.preferences.impl.notifications_NotificationSettingsView_Night_0_en",20420,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_10_en","features.preferences.impl.notifications_NotificationSettingsView_Night_10_en",20420,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_11_en","features.preferences.impl.notifications_NotificationSettingsView_Night_11_en",20420,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_12_en","features.preferences.impl.notifications_NotificationSettingsView_Night_12_en",20420,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_13_en","features.preferences.impl.notifications_NotificationSettingsView_Night_13_en",20420,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_1_en","features.preferences.impl.notifications_NotificationSettingsView_Night_1_en",20420,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_2_en","features.preferences.impl.notifications_NotificationSettingsView_Night_2_en",20420,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_3_en","features.preferences.impl.notifications_NotificationSettingsView_Night_3_en",20420,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_4_en","features.preferences.impl.notifications_NotificationSettingsView_Night_4_en",20420,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_5_en","features.preferences.impl.notifications_NotificationSettingsView_Night_5_en",20420,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_6_en","features.preferences.impl.notifications_NotificationSettingsView_Night_6_en",20420,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_7_en","features.preferences.impl.notifications_NotificationSettingsView_Night_7_en",20420,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_8_en","features.preferences.impl.notifications_NotificationSettingsView_Night_8_en",20420,], +["features.preferences.impl.notifications_NotificationSettingsView_Day_9_en","features.preferences.impl.notifications_NotificationSettingsView_Night_9_en",20420,], +["features.ftue.impl.notifications_NotificationsOptInView_Day_0_en","features.ftue.impl.notifications_NotificationsOptInView_Night_0_en",20420,], ["libraries.designsystem.atomic.pages_OnBoardingPage_Day_0_en","libraries.designsystem.atomic.pages_OnBoardingPage_Night_0_en",0,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_0_en","features.login.impl.screens.onboarding_OnBoardingView_Night_0_en",20413,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20413,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20413,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20413,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20413,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20413,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20413,], -["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20413,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_0_en","features.login.impl.screens.onboarding_OnBoardingView_Night_0_en",20420,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_1_en","features.login.impl.screens.onboarding_OnBoardingView_Night_1_en",20420,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_2_en","features.login.impl.screens.onboarding_OnBoardingView_Night_2_en",20420,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_3_en","features.login.impl.screens.onboarding_OnBoardingView_Night_3_en",20420,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_4_en","features.login.impl.screens.onboarding_OnBoardingView_Night_4_en",20420,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_5_en","features.login.impl.screens.onboarding_OnBoardingView_Night_5_en",20420,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_6_en","features.login.impl.screens.onboarding_OnBoardingView_Night_6_en",20420,], +["features.login.impl.screens.onboarding_OnBoardingView_Day_7_en","features.login.impl.screens.onboarding_OnBoardingView_Night_7_en",20420,], ["libraries.designsystem.background_OnboardingBackground_Day_0_en","libraries.designsystem.background_OnboardingBackground_Night_0_en",0,], -["libraries.matrix.ui.components_OrganizationHeader_Day_0_en","libraries.matrix.ui.components_OrganizationHeader_Night_0_en",20413,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20413,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20413,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20413,], +["libraries.matrix.ui.components_OrganizationHeader_Day_0_en","libraries.matrix.ui.components_OrganizationHeader_Night_0_en",20420,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_0_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_0_en",20420,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_10_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_10_en",20420,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_11_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_11_en",20420,], ["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_12_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_12_en",0,], ["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_13_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_13_en",0,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en",20413,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20413,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20413,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20413,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20413,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20413,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20413,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20413,], -["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20413,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_1_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_1_en",20420,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_2_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_2_en",20420,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_3_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_3_en",20420,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_4_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_4_en",20420,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_5_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_5_en",20420,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_6_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_6_en",20420,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_7_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_7_en",20420,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_8_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_8_en",20420,], +["features.verifysession.impl.outgoing_OutgoingVerificationView_Day_9_en","features.verifysession.impl.outgoing_OutgoingVerificationView_Night_9_en",20420,], ["libraries.designsystem.theme.components_OutlinedButtonLargeLowPadding_Buttons_en","",0,], ["libraries.designsystem.theme.components_OutlinedButtonLarge_Buttons_en","",0,], ["libraries.designsystem.theme.components_OutlinedButtonMediumLowPadding_Buttons_en","",0,], ["libraries.designsystem.theme.components_OutlinedButtonMedium_Buttons_en","",0,], ["libraries.designsystem.theme.components_OutlinedButtonSmall_Buttons_en","",0,], -["libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Day_0_en","libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Night_0_en",20413,], -["features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_en","features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Night_0_en",20413,], -["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20413,], -["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20413,], -["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20413,], -["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20413,], +["libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Day_0_en","libraries.mediaviewer.impl.local.pdf_PdfPagesErrorView_Night_0_en",20420,], +["features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Day_0_en","features.rolesandpermissions.impl.roles_PendingMemberRowWithLongName_Night_0_en",20420,], +["libraries.permissions.api_PermissionsView_Day_0_en","libraries.permissions.api_PermissionsView_Night_0_en",20420,], +["libraries.permissions.api_PermissionsView_Day_1_en","libraries.permissions.api_PermissionsView_Night_1_en",20420,], +["libraries.permissions.api_PermissionsView_Day_2_en","libraries.permissions.api_PermissionsView_Night_2_en",20420,], +["libraries.permissions.api_PermissionsView_Day_3_en","libraries.permissions.api_PermissionsView_Night_3_en",20420,], ["features.lockscreen.impl.components_PinEntryTextField_Day_0_en","features.lockscreen.impl.components_PinEntryTextField_Night_0_en",0,], ["libraries.designsystem.components_PinIcon_Day_0_en","libraries.designsystem.components_PinIcon_Night_0_en",0,], ["features.lockscreen.impl.unlock.keypad_PinKeypad_Day_0_en","features.lockscreen.impl.unlock.keypad_PinKeypad_Night_0_en",0,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_0_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_0_en",20413,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20413,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20413,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20413,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20413,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20413,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20413,], -["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20413,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20413,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20413,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20413,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20413,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20413,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20413,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20413,], -["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20413,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_0_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_0_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_1_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_1_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_2_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_2_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_3_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_3_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_4_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_4_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_5_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_5_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_6_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_6_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockViewInApp_Day_7_en","features.lockscreen.impl.unlock_PinUnlockViewInApp_Night_7_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_0_en","features.lockscreen.impl.unlock_PinUnlockView_Night_0_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_1_en","features.lockscreen.impl.unlock_PinUnlockView_Night_1_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_2_en","features.lockscreen.impl.unlock_PinUnlockView_Night_2_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_3_en","features.lockscreen.impl.unlock_PinUnlockView_Night_3_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_4_en","features.lockscreen.impl.unlock_PinUnlockView_Night_4_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_5_en","features.lockscreen.impl.unlock_PinUnlockView_Night_5_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_6_en","features.lockscreen.impl.unlock_PinUnlockView_Night_6_en",20420,], +["features.lockscreen.impl.unlock_PinUnlockView_Day_7_en","features.lockscreen.impl.unlock_PinUnlockView_Night_7_en",20420,], ["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_0_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_0_en",0,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_10_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_10_en",20413,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20413,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20413,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20413,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20413,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20413,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20413,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20413,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20413,], -["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20413,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20413,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20413,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20413,], -["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20413,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_10_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_10_en",20420,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_1_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_1_en",20420,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_2_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_2_en",20420,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_3_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_3_en",20420,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_4_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_4_en",20420,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_5_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_5_en",20420,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_6_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_6_en",20420,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_7_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_7_en",20420,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_8_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_8_en",20420,], +["features.messages.impl.pinned.banner_PinnedMessagesBannerView_Day_9_en","features.messages.impl.pinned.banner_PinnedMessagesBannerView_Night_9_en",20420,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_0_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_0_en",20420,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_1_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_1_en",20420,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_2_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_2_en",20420,], +["features.messages.impl.pinned.list_PinnedMessagesListView_Day_3_en","features.messages.impl.pinned.list_PinnedMessagesListView_Night_3_en",20420,], ["libraries.designsystem.atomic.atoms_PlaceholderAtom_Day_0_en","libraries.designsystem.atomic.atoms_PlaceholderAtom_Night_0_en",0,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20413,], -["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20413,], -["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20413,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20413,], -["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20413,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedNotSelected_Night_0_en",20420,], +["features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewDisclosedSelected_Night_0_en",20420,], +["features.poll.api.pollcontent_PollAnswerViewEndedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedSelected_Night_0_en",20420,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerNotSelected_Night_0_en",20420,], +["features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewEndedWinnerSelected_Night_0_en",20420,], ["features.poll.api.pollcontent_PollAnswerViewUndisclosedNotSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewUndisclosedNotSelected_Night_0_en",0,], ["features.poll.api.pollcontent_PollAnswerViewUndisclosedSelected_Day_0_en","features.poll.api.pollcontent_PollAnswerViewUndisclosedSelected_Night_0_en",0,], -["features.poll.api.pollcontent_PollContentViewCreatorEditable_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEditable_Night_0_en",20413,], -["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20413,], -["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20413,], -["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20413,], -["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20413,], -["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20413,], -["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20413,], -["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20413,], -["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20413,], -["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20413,], -["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20413,], +["features.poll.api.pollcontent_PollContentViewCreatorEditable_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEditable_Night_0_en",20420,], +["features.poll.api.pollcontent_PollContentViewCreatorEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewCreatorEnded_Night_0_en",20420,], +["features.poll.api.pollcontent_PollContentViewCreator_Day_0_en","features.poll.api.pollcontent_PollContentViewCreator_Night_0_en",20420,], +["features.poll.api.pollcontent_PollContentViewDisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewDisclosed_Night_0_en",20420,], +["features.poll.api.pollcontent_PollContentViewEnded_Day_0_en","features.poll.api.pollcontent_PollContentViewEnded_Night_0_en",20420,], +["features.poll.api.pollcontent_PollContentViewUndisclosed_Day_0_en","features.poll.api.pollcontent_PollContentViewUndisclosed_Night_0_en",20420,], +["features.poll.impl.history_PollHistoryView_Day_0_en","features.poll.impl.history_PollHistoryView_Night_0_en",20420,], +["features.poll.impl.history_PollHistoryView_Day_1_en","features.poll.impl.history_PollHistoryView_Night_1_en",20420,], +["features.poll.impl.history_PollHistoryView_Day_2_en","features.poll.impl.history_PollHistoryView_Night_2_en",20420,], +["features.poll.impl.history_PollHistoryView_Day_3_en","features.poll.impl.history_PollHistoryView_Night_3_en",20420,], +["features.poll.impl.history_PollHistoryView_Day_4_en","features.poll.impl.history_PollHistoryView_Night_4_en",20420,], ["features.poll.api.pollcontent_PollTitleView_Day_0_en","features.poll.api.pollcontent_PollTitleView_Night_0_en",0,], ["libraries.designsystem.components.preferences_PreferenceCategory_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceCheckbox_Preferences_en","",0,], @@ -801,211 +802,205 @@ export const screenshots = [ ["libraries.designsystem.components.preferences_PreferenceRow_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceSlide_Preferences_en","",0,], ["libraries.designsystem.components.preferences_PreferenceSwitch_Preferences_en","",0,], -["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20413,], -["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20413,], -["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20413,], -["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20413,], +["features.preferences.impl.root_PreferencesRootViewDark_0_en","",20420,], +["features.preferences.impl.root_PreferencesRootViewDark_1_en","",20420,], +["features.preferences.impl.root_PreferencesRootViewLight_0_en","",20420,], +["features.preferences.impl.root_PreferencesRootViewLight_1_en","",20420,], ["features.messages.impl.timeline.components.event_ProgressButton_Day_0_en","features.messages.impl.timeline.components.event_ProgressButton_Night_0_en",0,], -["libraries.designsystem.components_ProgressDialogContent_Dialogs_en","",20413,], -["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20413,], +["libraries.designsystem.components_ProgressDialogContent_Dialogs_en","",20420,], +["libraries.designsystem.components_ProgressDialogWithContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithContent_Night_0_en",20420,], ["libraries.designsystem.components_ProgressDialogWithTextAndContent_Day_0_en","libraries.designsystem.components_ProgressDialogWithTextAndContent_Night_0_en",0,], -["libraries.designsystem.components_ProgressDialog_Day_0_en","libraries.designsystem.components_ProgressDialog_Night_0_en",20413,], -["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20413,], -["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20413,], -["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20413,], -["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20413,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20413,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20413,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20413,], -["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20413,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20413,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20413,], -["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20413,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20413,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20413,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20413,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20413,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20413,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20413,], -["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20413,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20413,], -["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20413,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20413,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20413,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20413,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20413,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20413,], -["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20413,], +["libraries.designsystem.components_ProgressDialog_Day_0_en","libraries.designsystem.components_ProgressDialog_Night_0_en",20420,], +["features.messages.impl.timeline.protection_ProtectedView_Day_0_en","features.messages.impl.timeline.protection_ProtectedView_Night_0_en",20420,], +["features.messages.impl.timeline.protection_ProtectedView_Day_1_en","features.messages.impl.timeline.protection_ProtectedView_Night_1_en",20420,], +["features.messages.impl.timeline.protection_ProtectedView_Day_2_en","features.messages.impl.timeline.protection_ProtectedView_Night_2_en",20420,], +["features.messages.impl.timeline.protection_ProtectedView_Day_3_en","features.messages.impl.timeline.protection_ProtectedView_Night_3_en",20420,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_0_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_0_en",20420,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_1_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_1_en",20420,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_2_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_2_en",20420,], +["libraries.troubleshoot.impl.history_PushHistoryView_Day_3_en","libraries.troubleshoot.impl.history_PushHistoryView_Night_3_en",20420,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_0_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_0_en",20420,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_1_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_1_en",20420,], +["features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Day_2_en","features.login.impl.screens.qrcode.confirmation_QrCodeConfirmationView_Night_2_en",20420,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_0_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_0_en",20420,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_1_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_1_en",20420,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_2_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_2_en",20420,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_3_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_3_en",20420,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_4_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_4_en",20420,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_5_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_5_en",20420,], +["features.login.impl.screens.qrcode.error_QrCodeErrorView_Day_6_en","features.login.impl.screens.qrcode.error_QrCodeErrorView_Night_6_en",20420,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_0_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_0_en",20420,], +["features.login.impl.screens.qrcode.intro_QrCodeIntroView_Day_1_en","features.login.impl.screens.qrcode.intro_QrCodeIntroView_Night_1_en",20420,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_0_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_0_en",20420,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_1_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_1_en",20420,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_2_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_2_en",20420,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_3_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_3_en",20420,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_4_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_4_en",20420,], +["features.login.impl.screens.qrcode.scan_QrCodeScanView_Day_5_en","features.login.impl.screens.qrcode.scan_QrCodeScanView_Night_5_en",20420,], ["libraries.designsystem.theme.components_RadioButton_Toggles_en","",0,], -["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20413,], -["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20413,], +["features.rageshake.api.detection_RageshakeDialogContent_Day_0_en","features.rageshake.api.detection_RageshakeDialogContent_Night_0_en",20420,], +["features.rageshake.api.preferences_RageshakePreferencesView_Day_0_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_0_en",20420,], ["features.rageshake.api.preferences_RageshakePreferencesView_Day_1_en","features.rageshake.api.preferences_RageshakePreferencesView_Night_1_en",0,], ["features.messages.impl.timeline.components.reactionsummary_ReactionSummaryViewContent_Day_0_en","features.messages.impl.timeline.components.reactionsummary_ReactionSummaryViewContent_Night_0_en",0,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_0_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_0_en",20413,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20413,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20413,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20413,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20413,], -["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20413,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20413,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20413,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20413,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20413,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20413,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20413,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20413,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20413,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20413,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20413,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20413,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20413,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20413,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20413,], -["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20413,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_0_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_0_en",20420,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_1_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_1_en",20420,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_2_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_2_en",20420,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_3_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_3_en",20420,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_4_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_4_en",20420,], +["features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Day_5_en","features.messages.impl.timeline.components.receipt.bottomsheet_ReadReceiptBottomSheet_Night_5_en",20420,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_0_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_0_en",20420,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_10_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_10_en",20420,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_11_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_11_en",20420,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_12_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_12_en",20420,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_13_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_13_en",20420,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_14_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_14_en",20420,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_1_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_1_en",20420,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_2_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_2_en",20420,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_3_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_3_en",20420,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_4_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_4_en",20420,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_5_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_5_en",20420,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_6_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_6_en",20420,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_7_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_7_en",20420,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_8_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_8_en",20420,], +["features.securebackup.impl.setup.views_RecoveryKeyView_Day_9_en","features.securebackup.impl.setup.views_RecoveryKeyView_Night_9_en",20420,], ["libraries.designsystem.atomic.atoms_RedIndicatorAtom_Day_0_en","libraries.designsystem.atomic.atoms_RedIndicatorAtom_Night_0_en",0,], ["features.messages.impl.timeline.components_ReplySwipeIndicator_Day_0_en","features.messages.impl.timeline.components_ReplySwipeIndicator_Night_0_en",0,], -["features.messages.impl.report_ReportMessageView_Day_0_en","features.messages.impl.report_ReportMessageView_Night_0_en",20413,], -["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20413,], -["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20413,], -["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20413,], -["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20413,], -["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20413,], -["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20413,], -["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20413,], -["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20413,], -["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20413,], -["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20413,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20413,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20413,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20413,], -["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20413,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20413,], -["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20413,], +["features.messages.impl.report_ReportMessageView_Day_0_en","features.messages.impl.report_ReportMessageView_Night_0_en",20420,], +["features.messages.impl.report_ReportMessageView_Day_1_en","features.messages.impl.report_ReportMessageView_Night_1_en",20420,], +["features.messages.impl.report_ReportMessageView_Day_2_en","features.messages.impl.report_ReportMessageView_Night_2_en",20420,], +["features.messages.impl.report_ReportMessageView_Day_3_en","features.messages.impl.report_ReportMessageView_Night_3_en",20420,], +["features.messages.impl.report_ReportMessageView_Day_4_en","features.messages.impl.report_ReportMessageView_Night_4_en",20420,], +["features.messages.impl.report_ReportMessageView_Day_5_en","features.messages.impl.report_ReportMessageView_Night_5_en",20420,], +["features.reportroom.impl_ReportRoomView_Day_0_en","features.reportroom.impl_ReportRoomView_Night_0_en",20420,], +["features.reportroom.impl_ReportRoomView_Day_1_en","features.reportroom.impl_ReportRoomView_Night_1_en",20420,], +["features.reportroom.impl_ReportRoomView_Day_2_en","features.reportroom.impl_ReportRoomView_Night_2_en",20420,], +["features.reportroom.impl_ReportRoomView_Day_3_en","features.reportroom.impl_ReportRoomView_Night_3_en",20420,], +["features.reportroom.impl_ReportRoomView_Day_4_en","features.reportroom.impl_ReportRoomView_Night_4_en",20420,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_0_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_0_en",20420,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_1_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_1_en",20420,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_2_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_2_en",20420,], +["features.securebackup.impl.reset.password_ResetIdentityPasswordView_Day_3_en","features.securebackup.impl.reset.password_ResetIdentityPasswordView_Night_3_en",20420,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_0_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_0_en",20420,], +["features.securebackup.impl.reset.root_ResetIdentityRootView_Day_1_en","features.securebackup.impl.reset.root_ResetIdentityRootView_Night_1_en",20420,], ["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_0_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_0_en",0,], -["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_1_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_1_en",20413,], -["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20413,], -["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20413,], -["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20413,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20413,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20413,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20413,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20413,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20413,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20413,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20413,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20413,], -["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20413,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_1_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_1_en",20420,], +["features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Day_2_en","features.messages.impl.crypto.sendfailure.resolve_ResolveVerifiedUserSendFailureView_Night_2_en",20420,], +["libraries.designsystem.components.dialogs_RetryDialogContent_Dialogs_en","",20420,], +["libraries.designsystem.components.dialogs_RetryDialog_Day_0_en","libraries.designsystem.components.dialogs_RetryDialog_Night_0_en",20420,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_0_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_0_en",20420,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_1_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_1_en",20420,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_2_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_2_en",20420,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_3_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_3_en",20420,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_4_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_4_en",20420,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_5_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_5_en",20420,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_6_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_6_en",20420,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_7_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_7_en",20420,], +["features.rolesandpermissions.impl.root_RolesAndPermissionsView_Day_8_en","features.rolesandpermissions.impl.root_RolesAndPermissionsView_Night_8_en",20420,], ["libraries.matrix.ui.room.address_RoomAddressField_Day_0_en","libraries.matrix.ui.room.address_RoomAddressField_Night_0_en",0,], ["features.roomaliasresolver.impl_RoomAliasResolverView_Day_0_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_0_en",0,], -["features.roomaliasresolver.impl_RoomAliasResolverView_Day_1_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_1_en",20413,], -["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20413,], -["features.roomdetails.impl_RoomDetailsDark_0_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_10_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_11_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_12_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_13_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_14_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_15_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_16_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_17_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_18_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_19_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_1_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_2_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_3_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_4_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_5_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_6_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_7_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_8_en","",20413,], -["features.roomdetails.impl_RoomDetailsDark_9_en","",20413,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_0_en",20413,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_1_en",20413,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_2_en",20413,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_3_en",20413,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_4_en",20413,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_5_en",20413,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_6_en",20413,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_7_en",20413,], -["features.roomdetails.impl.edit_RoomDetailsEditView_Day_8_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_8_en",20413,], -["features.roomdetails.impl_RoomDetails_0_en","",20413,], -["features.roomdetails.impl_RoomDetails_10_en","",20413,], -["features.roomdetails.impl_RoomDetails_11_en","",20413,], -["features.roomdetails.impl_RoomDetails_12_en","",20413,], -["features.roomdetails.impl_RoomDetails_13_en","",20413,], -["features.roomdetails.impl_RoomDetails_14_en","",20413,], -["features.roomdetails.impl_RoomDetails_15_en","",20413,], -["features.roomdetails.impl_RoomDetails_16_en","",20413,], -["features.roomdetails.impl_RoomDetails_17_en","",20413,], -["features.roomdetails.impl_RoomDetails_18_en","",20413,], -["features.roomdetails.impl_RoomDetails_19_en","",20413,], -["features.roomdetails.impl_RoomDetails_1_en","",20413,], -["features.roomdetails.impl_RoomDetails_2_en","",20413,], -["features.roomdetails.impl_RoomDetails_3_en","",20413,], -["features.roomdetails.impl_RoomDetails_4_en","",20413,], -["features.roomdetails.impl_RoomDetails_5_en","",20413,], -["features.roomdetails.impl_RoomDetails_6_en","",20413,], -["features.roomdetails.impl_RoomDetails_7_en","",20413,], -["features.roomdetails.impl_RoomDetails_8_en","",20413,], -["features.roomdetails.impl_RoomDetails_9_en","",20413,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20413,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20413,], -["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20413,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20413,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20413,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20413,], -["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20413,], -["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20413,], -["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20413,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_1_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_1_en",20420,], +["features.roomaliasresolver.impl_RoomAliasResolverView_Day_2_en","features.roomaliasresolver.impl_RoomAliasResolverView_Night_2_en",20420,], +["features.roomdetails.impl_RoomDetailsDark_0_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_10_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_11_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_12_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_13_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_14_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_15_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_16_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_17_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_18_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_19_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_1_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_2_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_3_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_4_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_5_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_6_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_7_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_8_en","",20420,], +["features.roomdetails.impl_RoomDetailsDark_9_en","",20420,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_0_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_0_en",20420,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_1_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_1_en",20420,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_2_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_2_en",20420,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_3_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_3_en",20420,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_4_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_4_en",20420,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_5_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_5_en",20420,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_6_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_6_en",20420,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_7_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_7_en",20420,], +["features.roomdetails.impl.edit_RoomDetailsEditView_Day_8_en","features.roomdetails.impl.edit_RoomDetailsEditView_Night_8_en",20420,], +["features.roomdetails.impl_RoomDetails_0_en","",20420,], +["features.roomdetails.impl_RoomDetails_10_en","",20420,], +["features.roomdetails.impl_RoomDetails_11_en","",20420,], +["features.roomdetails.impl_RoomDetails_12_en","",20420,], +["features.roomdetails.impl_RoomDetails_13_en","",20420,], +["features.roomdetails.impl_RoomDetails_14_en","",20420,], +["features.roomdetails.impl_RoomDetails_15_en","",20420,], +["features.roomdetails.impl_RoomDetails_16_en","",20420,], +["features.roomdetails.impl_RoomDetails_17_en","",20420,], +["features.roomdetails.impl_RoomDetails_18_en","",20420,], +["features.roomdetails.impl_RoomDetails_19_en","",20420,], +["features.roomdetails.impl_RoomDetails_1_en","",20420,], +["features.roomdetails.impl_RoomDetails_2_en","",20420,], +["features.roomdetails.impl_RoomDetails_3_en","",20420,], +["features.roomdetails.impl_RoomDetails_4_en","",20420,], +["features.roomdetails.impl_RoomDetails_5_en","",20420,], +["features.roomdetails.impl_RoomDetails_6_en","",20420,], +["features.roomdetails.impl_RoomDetails_7_en","",20420,], +["features.roomdetails.impl_RoomDetails_8_en","",20420,], +["features.roomdetails.impl_RoomDetails_9_en","",20420,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_0_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_0_en",20420,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_1_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_1_en",20420,], +["features.roomdirectory.impl.root_RoomDirectoryView_Day_2_en","features.roomdirectory.impl.root_RoomDirectoryView_Night_2_en",20420,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_0_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_0_en",20420,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_1_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_1_en",20420,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_2_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_2_en",20420,], +["features.roomdetails.impl.invite_RoomInviteMembersView_Day_3_en","features.roomdetails.impl.invite_RoomInviteMembersView_Night_3_en",20420,], +["features.home.impl.components_RoomListContentView_Day_0_en","features.home.impl.components_RoomListContentView_Night_0_en",20420,], +["features.home.impl.components_RoomListContentView_Day_1_en","features.home.impl.components_RoomListContentView_Night_1_en",20420,], ["features.home.impl.components_RoomListContentView_Day_2_en","features.home.impl.components_RoomListContentView_Night_2_en",0,], -["features.home.impl.components_RoomListContentView_Day_3_en","features.home.impl.components_RoomListContentView_Night_3_en",20413,], -["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20413,], -["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20413,], -["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20413,], -["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20413,], -["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20413,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20413,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20413,], -["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20413,], +["features.home.impl.components_RoomListContentView_Day_3_en","features.home.impl.components_RoomListContentView_Night_3_en",20420,], +["features.home.impl.components_RoomListContentView_Day_4_en","features.home.impl.components_RoomListContentView_Night_4_en",20420,], +["features.home.impl.components_RoomListContentView_Day_5_en","features.home.impl.components_RoomListContentView_Night_5_en",20420,], +["features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Day_0_en","features.home.impl.roomlist_RoomListDeclineInviteMenuContent_Night_0_en",20420,], +["features.home.impl.filters_RoomListFiltersView_Day_0_en","features.home.impl.filters_RoomListFiltersView_Night_0_en",20420,], +["features.home.impl.filters_RoomListFiltersView_Day_1_en","features.home.impl.filters_RoomListFiltersView_Night_1_en",20420,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_0_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_0_en",20420,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_1_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_1_en",20420,], +["features.home.impl.roomlist_RoomListModalBottomSheetContent_Day_2_en","features.home.impl.roomlist_RoomListModalBottomSheetContent_Night_2_en",20420,], ["features.home.impl.search_RoomListSearchContent_Day_0_en","features.home.impl.search_RoomListSearchContent_Night_0_en",0,], -["features.home.impl.search_RoomListSearchContent_Day_1_en","features.home.impl.search_RoomListSearchContent_Night_1_en",20413,], -["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_0_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_0_en",20413,], -["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_1_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_1_en",20413,], -["features.roomdetails.impl.members_RoomMemberListViewBanned_Day_2_en","features.roomdetails.impl.members_RoomMemberListViewBanned_Night_2_en",20413,], -["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20413,], -["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20413,], -["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20413,], -["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20413,], -["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20413,], -["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20413,], +["features.home.impl.search_RoomListSearchContent_Day_1_en","features.home.impl.search_RoomListSearchContent_Night_1_en",20420,], +["features.roomdetails.impl.members_RoomMemberListView_Day_0_en","features.roomdetails.impl.members_RoomMemberListView_Night_0_en",20420,], +["features.roomdetails.impl.members_RoomMemberListView_Day_1_en","features.roomdetails.impl.members_RoomMemberListView_Night_1_en",20420,], +["features.roomdetails.impl.members_RoomMemberListView_Day_2_en","features.roomdetails.impl.members_RoomMemberListView_Night_2_en",20420,], +["features.roomdetails.impl.members_RoomMemberListView_Day_3_en","features.roomdetails.impl.members_RoomMemberListView_Night_3_en",20420,], +["features.roomdetails.impl.members_RoomMemberListView_Day_4_en","features.roomdetails.impl.members_RoomMemberListView_Night_4_en",20420,], +["features.roomdetails.impl.members_RoomMemberListView_Day_5_en","features.roomdetails.impl.members_RoomMemberListView_Night_5_en",20420,], ["features.roomdetails.impl.members_RoomMemberListView_Day_6_en","features.roomdetails.impl.members_RoomMemberListView_Night_6_en",0,], -["features.roomdetails.impl.members_RoomMemberListView_Day_7_en","features.roomdetails.impl.members_RoomMemberListView_Night_7_en",20413,], -["features.roomdetails.impl.members_RoomMemberListView_Day_8_en","features.roomdetails.impl.members_RoomMemberListView_Night_8_en",20413,], -["features.roomdetails.impl.members_RoomMemberListView_Day_9_en","features.roomdetails.impl.members_RoomMemberListView_Night_9_en",20413,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20413,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20413,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20413,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20413,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20413,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20413,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20413,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20413,], -["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20413,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_0_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_0_en",20420,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_1_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_1_en",20420,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_2_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_2_en",20420,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_3_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_3_en",20420,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_4_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_4_en",20420,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_5_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_5_en",20420,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_6_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_6_en",20420,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_7_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_7_en",20420,], +["features.roommembermoderation.impl_RoomMemberModerationView_Day_8_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_8_en",20420,], ["features.roommembermoderation.impl_RoomMemberModerationView_Day_9_en","features.roommembermoderation.impl_RoomMemberModerationView_Night_9_en",0,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20413,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20413,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20413,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20413,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20413,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20413,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20413,], -["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20413,], -["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20413,], -["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20413,], -["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20413,], -["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20413,], -["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20413,], -["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20413,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsOption_Night_0_en",20420,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_0_en",20420,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_1_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_1_en",20420,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_2_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_2_en",20420,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_3_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_3_en",20420,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_4_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_4_en",20420,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_5_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_5_en",20420,], +["features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Day_6_en","features.roomdetails.impl.notificationsettings_RoomNotificationSettingsView_Night_6_en",20420,], +["libraries.roomselect.impl_RoomSelectView_Day_0_en","libraries.roomselect.impl_RoomSelectView_Night_0_en",20420,], +["libraries.roomselect.impl_RoomSelectView_Day_1_en","libraries.roomselect.impl_RoomSelectView_Night_1_en",20420,], +["libraries.roomselect.impl_RoomSelectView_Day_2_en","libraries.roomselect.impl_RoomSelectView_Night_2_en",20420,], +["libraries.roomselect.impl_RoomSelectView_Day_3_en","libraries.roomselect.impl_RoomSelectView_Night_3_en",20420,], +["libraries.roomselect.impl_RoomSelectView_Day_4_en","libraries.roomselect.impl_RoomSelectView_Night_4_en",20420,], +["libraries.roomselect.impl_RoomSelectView_Day_5_en","libraries.roomselect.impl_RoomSelectView_Night_5_en",20420,], ["features.home.impl.components_RoomSummaryPlaceholderRow_Day_0_en","features.home.impl.components_RoomSummaryPlaceholderRow_Night_0_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_0_en","features.home.impl.components_RoomSummaryRow_Night_0_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_10_en","features.home.impl.components_RoomSummaryRow_Night_10_en",0,], @@ -1028,14 +1023,14 @@ export const screenshots = [ ["features.home.impl.components_RoomSummaryRow_Day_26_en","features.home.impl.components_RoomSummaryRow_Night_26_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_27_en","features.home.impl.components_RoomSummaryRow_Night_27_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_28_en","features.home.impl.components_RoomSummaryRow_Night_28_en",0,], -["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20413,], -["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20413,], -["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20413,], -["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20413,], -["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20413,], -["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20413,], -["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20413,], -["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20413,], +["features.home.impl.components_RoomSummaryRow_Day_29_en","features.home.impl.components_RoomSummaryRow_Night_29_en",20420,], +["features.home.impl.components_RoomSummaryRow_Day_2_en","features.home.impl.components_RoomSummaryRow_Night_2_en",20420,], +["features.home.impl.components_RoomSummaryRow_Day_30_en","features.home.impl.components_RoomSummaryRow_Night_30_en",20420,], +["features.home.impl.components_RoomSummaryRow_Day_31_en","features.home.impl.components_RoomSummaryRow_Night_31_en",20420,], +["features.home.impl.components_RoomSummaryRow_Day_32_en","features.home.impl.components_RoomSummaryRow_Night_32_en",20420,], +["features.home.impl.components_RoomSummaryRow_Day_33_en","features.home.impl.components_RoomSummaryRow_Night_33_en",20420,], +["features.home.impl.components_RoomSummaryRow_Day_34_en","features.home.impl.components_RoomSummaryRow_Night_34_en",20420,], +["features.home.impl.components_RoomSummaryRow_Day_35_en","features.home.impl.components_RoomSummaryRow_Night_35_en",20420,], ["features.home.impl.components_RoomSummaryRow_Day_3_en","features.home.impl.components_RoomSummaryRow_Night_3_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_4_en","features.home.impl.components_RoomSummaryRow_Night_4_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_5_en","features.home.impl.components_RoomSummaryRow_Night_5_en",0,], @@ -1043,83 +1038,105 @@ export const screenshots = [ ["features.home.impl.components_RoomSummaryRow_Day_7_en","features.home.impl.components_RoomSummaryRow_Night_7_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_8_en","features.home.impl.components_RoomSummaryRow_Night_8_en",0,], ["features.home.impl.components_RoomSummaryRow_Day_9_en","features.home.impl.components_RoomSummaryRow_Night_9_en",0,], -["appnav.root_RootView_Day_0_en","appnav.root_RootView_Night_0_en",20413,], -["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20413,], -["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20413,], +["appnav.root_RootView_Day_0_en","appnav.root_RootView_Night_0_en",20420,], +["appnav.root_RootView_Day_1_en","appnav.root_RootView_Night_1_en",20420,], +["appnav.root_RootView_Day_2_en","appnav.root_RootView_Night_2_en",20420,], ["appicon.enterprise_RoundIcon_en","",0,], ["appicon.element_RoundIcon_en","",0,], ["libraries.designsystem.atomic.atoms_RoundedIconAtom_Day_0_en","libraries.designsystem.atomic.atoms_RoundedIconAtom_Night_0_en",0,], -["features.verifysession.impl.emoji_SasEmojis_Day_0_en","features.verifysession.impl.emoji_SasEmojis_Night_0_en",20413,], -["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20413,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20413,], -["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20413,], +["features.verifysession.impl.emoji_SasEmojis_Day_0_en","features.verifysession.impl.emoji_SasEmojis_Night_0_en",20420,], +["libraries.designsystem.components.dialogs_SaveChangesDialog_Day_0_en","libraries.designsystem.components.dialogs_SaveChangesDialog_Night_0_en",20420,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_0_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_0_en",20420,], +["features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Day_1_en","features.login.impl.screens.searchaccountprovider_SearchAccountProviderView_Night_1_en",20420,], ["libraries.designsystem.theme.components_SearchBarActiveNoneQuery_Search_views_en","",0,], ["libraries.designsystem.theme.components_SearchBarActiveWithContent_Search_views_en","",0,], -["libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en","",20413,], +["libraries.designsystem.theme.components_SearchBarActiveWithNoResults_Search_views_en","",20420,], ["libraries.designsystem.theme.components_SearchBarActiveWithQueryNoBackButton_Search_views_en","",0,], ["libraries.designsystem.theme.components_SearchBarActiveWithQuery_Search_views_en","",0,], ["libraries.designsystem.theme.components_SearchBarInactive_Search_views_en","",0,], -["features.startchat.impl.components_SearchMultipleUsersResultItem_en","",20413,], -["features.startchat.impl.components_SearchSingleUserResultItem_en","",20413,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20413,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20413,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20413,], -["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20413,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20413,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20413,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20413,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20413,], -["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20413,], -["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20413,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20413,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20413,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20413,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20413,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20413,], -["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20413,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20413,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20413,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20413,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20413,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20413,], -["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_0_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_1_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_2_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_3_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_4_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_5_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_6_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_7_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_8_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewDark_9_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_0_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_1_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_2_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_3_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_4_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_5_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_6_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_7_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_8_en","",20413,], -["features.roomdetails.impl.securityandprivacy_SecurityAndPrivacyViewLight_9_en","",20413,], +["libraries.designsystem.theme.components_SearchFieldsDark_Search_views_en","",0,], +["libraries.designsystem.theme.components_SearchFieldsLight_Search_views_en","",0,], +["features.startchat.impl.components_SearchMultipleUsersResultItem_en","",20420,], +["features.startchat.impl.components_SearchSingleUserResultItem_en","",20420,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_0_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_0_en",20420,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_1_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_1_en",20420,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_2_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_2_en",20420,], +["features.securebackup.impl.disable_SecureBackupDisableView_Day_3_en","features.securebackup.impl.disable_SecureBackupDisableView_Night_3_en",20420,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_0_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_0_en",20420,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_1_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_1_en",20420,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_2_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_2_en",20420,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_3_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_3_en",20420,], +["features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Day_4_en","features.securebackup.impl.enter_SecureBackupEnterRecoveryKeyView_Night_4_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_0_en","features.securebackup.impl.root_SecureBackupRootView_Night_0_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_10_en","features.securebackup.impl.root_SecureBackupRootView_Night_10_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_11_en","features.securebackup.impl.root_SecureBackupRootView_Night_11_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_12_en","features.securebackup.impl.root_SecureBackupRootView_Night_12_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_13_en","features.securebackup.impl.root_SecureBackupRootView_Night_13_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_14_en","features.securebackup.impl.root_SecureBackupRootView_Night_14_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_15_en","features.securebackup.impl.root_SecureBackupRootView_Night_15_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_16_en","features.securebackup.impl.root_SecureBackupRootView_Night_16_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_17_en","features.securebackup.impl.root_SecureBackupRootView_Night_17_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_1_en","features.securebackup.impl.root_SecureBackupRootView_Night_1_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_2_en","features.securebackup.impl.root_SecureBackupRootView_Night_2_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_3_en","features.securebackup.impl.root_SecureBackupRootView_Night_3_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_4_en","features.securebackup.impl.root_SecureBackupRootView_Night_4_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_5_en","features.securebackup.impl.root_SecureBackupRootView_Night_5_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_6_en","features.securebackup.impl.root_SecureBackupRootView_Night_6_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_7_en","features.securebackup.impl.root_SecureBackupRootView_Night_7_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_8_en","features.securebackup.impl.root_SecureBackupRootView_Night_8_en",20420,], +["features.securebackup.impl.root_SecureBackupRootView_Day_9_en","features.securebackup.impl.root_SecureBackupRootView_Night_9_en",20420,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_0_en",20420,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_1_en",20420,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_2_en",20420,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_3_en",20420,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_4_en",20420,], +["features.securebackup.impl.setup_SecureBackupSetupViewChange_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupViewChange_Night_5_en",20420,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_0_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_0_en",20420,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_1_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_1_en",20420,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_2_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_2_en",20420,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_3_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_3_en",20420,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_4_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_4_en",20420,], +["features.securebackup.impl.setup_SecureBackupSetupView_Day_5_en","features.securebackup.impl.setup_SecureBackupSetupView_Night_5_en",20420,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en","",0,], +["features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en","",0,], ["libraries.designsystem.atomic.atoms_SelectedIndicatorAtom_Day_0_en","libraries.designsystem.atomic.atoms_SelectedIndicatorAtom_Night_0_en",0,], ["libraries.matrix.ui.components_SelectedRoomRtl_Day_0_en","libraries.matrix.ui.components_SelectedRoomRtl_Night_0_en",0,], ["libraries.matrix.ui.components_SelectedRoomRtl_Day_1_en","libraries.matrix.ui.components_SelectedRoomRtl_Night_1_en",0,], @@ -1133,11 +1150,11 @@ export const screenshots = [ ["libraries.matrix.ui.components_SelectedUser_Day_1_en","libraries.matrix.ui.components_SelectedUser_Night_1_en",0,], ["libraries.matrix.ui.components_SelectedUsersRowList_Day_0_en","libraries.matrix.ui.components_SelectedUsersRowList_Night_0_en",0,], ["libraries.textcomposer.components_SendButton_Day_0_en","libraries.textcomposer.components_SendButton_Night_0_en",0,], -["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20413,], -["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20413,], -["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20413,], -["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20413,], -["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20413,], +["features.location.impl.send_SendLocationView_Day_0_en","features.location.impl.send_SendLocationView_Night_0_en",20420,], +["features.location.impl.send_SendLocationView_Day_1_en","features.location.impl.send_SendLocationView_Night_1_en",20420,], +["features.location.impl.send_SendLocationView_Day_2_en","features.location.impl.send_SendLocationView_Night_2_en",20420,], +["features.location.impl.send_SendLocationView_Day_3_en","features.location.impl.send_SendLocationView_Night_3_en",20420,], +["features.location.impl.send_SendLocationView_Day_4_en","features.location.impl.send_SendLocationView_Night_4_en",20420,], ["libraries.matrix.ui.messages.sender_SenderName_Day_0_en","libraries.matrix.ui.messages.sender_SenderName_Night_0_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_1_en","libraries.matrix.ui.messages.sender_SenderName_Night_1_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_2_en","libraries.matrix.ui.messages.sender_SenderName_Night_2_en",0,], @@ -1147,27 +1164,27 @@ export const screenshots = [ ["libraries.matrix.ui.messages.sender_SenderName_Day_6_en","libraries.matrix.ui.messages.sender_SenderName_Night_6_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_7_en","libraries.matrix.ui.messages.sender_SenderName_Night_7_en",0,], ["libraries.matrix.ui.messages.sender_SenderName_Day_8_en","libraries.matrix.ui.messages.sender_SenderName_Night_8_en",0,], -["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20413,], -["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20413,], -["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20413,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20413,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20413,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20413,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20413,], -["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20413,], +["features.verifysession.impl.incoming.ui_SessionDetailsView_Day_0_en","features.verifysession.impl.incoming.ui_SessionDetailsView_Night_0_en",20420,], +["features.home.impl.components_SetUpRecoveryKeyBanner_Day_0_en","features.home.impl.components_SetUpRecoveryKeyBanner_Night_0_en",20420,], +["features.lockscreen.impl.setup.biometric_SetupBiometricView_Day_0_en","features.lockscreen.impl.setup.biometric_SetupBiometricView_Night_0_en",20420,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_0_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_0_en",20420,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_1_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_1_en",20420,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_2_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_2_en",20420,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_3_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_3_en",20420,], +["features.lockscreen.impl.setup.pin_SetupPinView_Day_4_en","features.lockscreen.impl.setup.pin_SetupPinView_Night_4_en",20420,], ["features.share.impl_ShareView_Day_0_en","features.share.impl_ShareView_Night_0_en",0,], ["features.share.impl_ShareView_Day_1_en","features.share.impl_ShareView_Night_1_en",0,], ["features.share.impl_ShareView_Day_2_en","features.share.impl_ShareView_Night_2_en",0,], -["features.share.impl_ShareView_Day_3_en","features.share.impl_ShareView_Night_3_en",20413,], -["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20413,], -["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20413,], -["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20413,], -["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20413,], -["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20413,], -["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20413,], -["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20413,], -["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20413,], -["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20413,], +["features.share.impl_ShareView_Day_3_en","features.share.impl_ShareView_Night_3_en",20420,], +["features.location.impl.show_ShowLocationView_Day_0_en","features.location.impl.show_ShowLocationView_Night_0_en",20420,], +["features.location.impl.show_ShowLocationView_Day_1_en","features.location.impl.show_ShowLocationView_Night_1_en",20420,], +["features.location.impl.show_ShowLocationView_Day_2_en","features.location.impl.show_ShowLocationView_Night_2_en",20420,], +["features.location.impl.show_ShowLocationView_Day_3_en","features.location.impl.show_ShowLocationView_Night_3_en",20420,], +["features.location.impl.show_ShowLocationView_Day_4_en","features.location.impl.show_ShowLocationView_Night_4_en",20420,], +["features.location.impl.show_ShowLocationView_Day_5_en","features.location.impl.show_ShowLocationView_Night_5_en",20420,], +["features.location.impl.show_ShowLocationView_Day_6_en","features.location.impl.show_ShowLocationView_Night_6_en",20420,], +["features.location.impl.show_ShowLocationView_Day_7_en","features.location.impl.show_ShowLocationView_Night_7_en",20420,], +["features.signedout.impl_SignedOutView_Day_0_en","features.signedout.impl_SignedOutView_Night_0_en",20420,], ["libraries.designsystem.components_SimpleModalBottomSheet_Day_0_en","libraries.designsystem.components_SimpleModalBottomSheet_Night_0_en",0,], ["libraries.designsystem.components.dialogs_SingleSelectionDialogContent_Dialogs_en","",0,], ["libraries.designsystem.components.dialogs_SingleSelectionDialog_Day_0_en","libraries.designsystem.components.dialogs_SingleSelectionDialog_Night_0_en",0,], @@ -1177,102 +1194,102 @@ export const screenshots = [ ["libraries.designsystem.components.list_SingleSelectionListItemUnselectedWithSupportingText_Single_selection_List_item_-_no_selection,_supporting_text_List_items_en","",0,], ["libraries.designsystem.components.list_SingleSelectionListItem_Single_selection_List_item_-_no_selection_List_items_en","",0,], ["libraries.designsystem.theme.components_Sliders_Sliders_en","",0,], -["features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Day_0_en","features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Night_0_en",20413,], +["features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Day_0_en","features.login.impl.dialogs_SlidingSyncNotSupportedDialog_Night_0_en",20420,], ["libraries.designsystem.theme.components_SnackbarWithActionAndCloseButton_Snackbar_with_action_and_close_button_Snackbars_en","",0,], ["libraries.designsystem.theme.components_SnackbarWithActionOnNewLineAndCloseButton_Snackbar_with_action_and_close_button_on_new_line_Snackbars_en","",0,], ["libraries.designsystem.theme.components_SnackbarWithActionOnNewLine_Snackbar_with_action_on_new_line_Snackbars_en","",0,], ["libraries.designsystem.theme.components_SnackbarWithAction_Snackbar_with_action_Snackbars_en","",0,], ["libraries.designsystem.theme.components_Snackbar_Snackbar_Snackbars_en","",0,], -["features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en","features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en",20413,], +["features.announcement.impl.spaces_SpaceAnnouncementView_Day_0_en","features.announcement.impl.spaces_SpaceAnnouncementView_Night_0_en",20420,], ["libraries.designsystem.components.avatar.internal_SpaceAvatar_Avatars_en","",0,], -["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20413,], -["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20413,], -["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20413,], +["libraries.matrix.ui.components_SpaceHeaderRootView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderRootView_Night_0_en",20420,], +["libraries.matrix.ui.components_SpaceHeaderView_Day_0_en","libraries.matrix.ui.components_SpaceHeaderView_Night_0_en",20420,], +["libraries.matrix.ui.components_SpaceInfoRow_Day_0_en","libraries.matrix.ui.components_SpaceInfoRow_Night_0_en",20420,], ["libraries.matrix.ui.components_SpaceMembersViewNoHeroes_Day_0_en","libraries.matrix.ui.components_SpaceMembersViewNoHeroes_Night_0_en",0,], ["libraries.matrix.ui.components_SpaceMembersView_Day_0_en","libraries.matrix.ui.components_SpaceMembersView_Night_0_en",0,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_0_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_0_en",20413,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20413,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20413,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20413,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20413,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20413,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20413,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20413,], -["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20413,], -["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20413,], -["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20413,], -["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20413,], -["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20413,], -["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20413,], -["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20413,], -["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20413,], -["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20413,], -["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20413,], -["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20413,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_0_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_0_en",20420,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_1_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_1_en",20420,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_2_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_2_en",20420,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_3_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_3_en",20420,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_4_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_4_en",20420,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_5_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_5_en",20420,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_6_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_6_en",20420,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_7_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_7_en",20420,], +["libraries.matrix.ui.components_SpaceRoomItemView_Day_8_en","libraries.matrix.ui.components_SpaceRoomItemView_Night_8_en",20420,], +["features.space.impl.settings_SpaceSettingsView_Day_0_en","features.space.impl.settings_SpaceSettingsView_Night_0_en",20420,], +["features.space.impl.settings_SpaceSettingsView_Day_1_en","features.space.impl.settings_SpaceSettingsView_Night_1_en",20420,], +["features.space.impl.settings_SpaceSettingsView_Day_2_en","features.space.impl.settings_SpaceSettingsView_Night_2_en",20420,], +["features.space.impl.settings_SpaceSettingsView_Day_3_en","features.space.impl.settings_SpaceSettingsView_Night_3_en",20420,], +["features.space.impl.root_SpaceView_Day_0_en","features.space.impl.root_SpaceView_Night_0_en",20420,], +["features.space.impl.root_SpaceView_Day_1_en","features.space.impl.root_SpaceView_Night_1_en",20420,], +["features.space.impl.root_SpaceView_Day_2_en","features.space.impl.root_SpaceView_Night_2_en",20420,], +["features.space.impl.root_SpaceView_Day_3_en","features.space.impl.root_SpaceView_Night_3_en",20420,], +["features.space.impl.root_SpaceView_Day_4_en","features.space.impl.root_SpaceView_Night_4_en",20420,], +["features.space.impl.root_SpaceView_Day_5_en","features.space.impl.root_SpaceView_Night_5_en",20420,], ["libraries.designsystem.modifiers_SquareSizeModifierInsideSquare_en","",0,], ["libraries.designsystem.modifiers_SquareSizeModifierLargeHeight_en","",0,], ["libraries.designsystem.modifiers_SquareSizeModifierLargeWidth_en","",0,], -["features.startchat.impl.root_StartChatView_Day_0_en","features.startchat.impl.root_StartChatView_Night_0_en",20413,], -["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20413,], -["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20413,], -["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20413,], -["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20413,], -["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20413,], -["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20413,], +["features.startchat.impl.root_StartChatView_Day_0_en","features.startchat.impl.root_StartChatView_Night_0_en",20420,], +["features.startchat.impl.root_StartChatView_Day_1_en","features.startchat.impl.root_StartChatView_Night_1_en",20420,], +["features.startchat.impl.root_StartChatView_Day_2_en","features.startchat.impl.root_StartChatView_Night_2_en",20420,], +["features.startchat.impl.root_StartChatView_Day_3_en","features.startchat.impl.root_StartChatView_Night_3_en",20420,], +["features.startchat.impl.root_StartChatView_Day_4_en","features.startchat.impl.root_StartChatView_Night_4_en",20420,], +["features.startchat.impl.root_StartChatView_Day_5_en","features.startchat.impl.root_StartChatView_Night_5_en",20420,], +["features.location.api.internal_StaticMapPlaceholder_Day_0_en","features.location.api.internal_StaticMapPlaceholder_Night_0_en",20420,], ["features.location.api_StaticMapView_Day_0_en","features.location.api_StaticMapView_Night_0_en",0,], -["features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en","features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en",20413,], +["features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Day_0_en","features.messages.impl.messagecomposer.suggestions_SuggestionsPickerView_Night_0_en",20420,], ["libraries.designsystem.atomic.pages_SunsetPage_Day_0_en","libraries.designsystem.atomic.pages_SunsetPage_Night_0_en",0,], ["libraries.designsystem.components.button_SuperButton_Day_0_en","libraries.designsystem.components.button_SuperButton_Night_0_en",0,], ["libraries.designsystem.theme.components_Surface_en","",0,], ["libraries.designsystem.theme.components_Switch_Toggles_en","",0,], -["appnav.loggedin_SyncStateView_Day_0_en","appnav.loggedin_SyncStateView_Night_0_en",20413,], +["appnav.loggedin_SyncStateView_Day_0_en","appnav.loggedin_SyncStateView_Night_0_en",20420,], ["libraries.designsystem.components.avatar.internal_TextAvatar_Avatars_en","",0,], ["libraries.designsystem.theme.components_TextButtonLargeLowPadding_Buttons_en","",0,], ["libraries.designsystem.theme.components_TextButtonLarge_Buttons_en","",0,], ["libraries.designsystem.theme.components_TextButtonMediumLowPadding_Buttons_en","",0,], ["libraries.designsystem.theme.components_TextButtonMedium_Buttons_en","",0,], ["libraries.designsystem.theme.components_TextButtonSmall_Buttons_en","",0,], -["libraries.textcomposer_TextComposerAddCaption_Day_0_en","libraries.textcomposer_TextComposerAddCaption_Night_0_en",20413,], -["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20413,], -["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20413,], -["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20413,], -["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20413,], -["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20413,], -["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20413,], -["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20413,], -["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20413,], -["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20413,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20413,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20413,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20413,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20413,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20413,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20413,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20413,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20413,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20413,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20413,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20413,], -["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20413,], -["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20413,], -["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20413,], -["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20413,], -["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20413,], -["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20413,], -["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20413,], -["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20413,], -["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20413,], -["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20413,], -["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20413,], -["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20413,], -["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20413,], -["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20413,], -["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20413,], -["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20413,], +["libraries.textcomposer_TextComposerAddCaption_Day_0_en","libraries.textcomposer_TextComposerAddCaption_Night_0_en",20420,], +["libraries.textcomposer_TextComposerCaption_Day_0_en","libraries.textcomposer_TextComposerCaption_Night_0_en",20420,], +["libraries.textcomposer_TextComposerEditCaption_Day_0_en","libraries.textcomposer_TextComposerEditCaption_Night_0_en",20420,], +["libraries.textcomposer_TextComposerEditNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerEditNotEncrypted_Night_0_en",20420,], +["libraries.textcomposer_TextComposerEdit_Day_0_en","libraries.textcomposer_TextComposerEdit_Night_0_en",20420,], +["libraries.textcomposer_TextComposerFormattingNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerFormattingNotEncrypted_Night_0_en",20420,], +["libraries.textcomposer_TextComposerFormatting_Day_0_en","libraries.textcomposer_TextComposerFormatting_Night_0_en",20420,], +["libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLinkWithoutText_Night_0_en",20420,], +["libraries.textcomposer_TextComposerLinkDialogCreateLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogCreateLink_Night_0_en",20420,], +["libraries.textcomposer_TextComposerLinkDialogEditLink_Day_0_en","libraries.textcomposer_TextComposerLinkDialogEditLink_Night_0_en",20420,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_0_en",20420,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_10_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_10_en",20420,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_11_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_11_en",20420,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_1_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_1_en",20420,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_2_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_2_en",20420,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_3_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_3_en",20420,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_4_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_4_en",20420,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_5_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_5_en",20420,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_6_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_6_en",20420,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_7_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_7_en",20420,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_8_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_8_en",20420,], +["libraries.textcomposer_TextComposerReplyNotEncrypted_Day_9_en","libraries.textcomposer_TextComposerReplyNotEncrypted_Night_9_en",20420,], +["libraries.textcomposer_TextComposerReply_Day_0_en","libraries.textcomposer_TextComposerReply_Night_0_en",20420,], +["libraries.textcomposer_TextComposerReply_Day_10_en","libraries.textcomposer_TextComposerReply_Night_10_en",20420,], +["libraries.textcomposer_TextComposerReply_Day_11_en","libraries.textcomposer_TextComposerReply_Night_11_en",20420,], +["libraries.textcomposer_TextComposerReply_Day_1_en","libraries.textcomposer_TextComposerReply_Night_1_en",20420,], +["libraries.textcomposer_TextComposerReply_Day_2_en","libraries.textcomposer_TextComposerReply_Night_2_en",20420,], +["libraries.textcomposer_TextComposerReply_Day_3_en","libraries.textcomposer_TextComposerReply_Night_3_en",20420,], +["libraries.textcomposer_TextComposerReply_Day_4_en","libraries.textcomposer_TextComposerReply_Night_4_en",20420,], +["libraries.textcomposer_TextComposerReply_Day_5_en","libraries.textcomposer_TextComposerReply_Night_5_en",20420,], +["libraries.textcomposer_TextComposerReply_Day_6_en","libraries.textcomposer_TextComposerReply_Night_6_en",20420,], +["libraries.textcomposer_TextComposerReply_Day_7_en","libraries.textcomposer_TextComposerReply_Night_7_en",20420,], +["libraries.textcomposer_TextComposerReply_Day_8_en","libraries.textcomposer_TextComposerReply_Night_8_en",20420,], +["libraries.textcomposer_TextComposerReply_Day_9_en","libraries.textcomposer_TextComposerReply_Night_9_en",20420,], +["libraries.textcomposer_TextComposerSimpleNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerSimpleNotEncrypted_Night_0_en",20420,], +["libraries.textcomposer_TextComposerSimple_Day_0_en","libraries.textcomposer_TextComposerSimple_Night_0_en",20420,], +["libraries.textcomposer_TextComposerVoiceNotEncrypted_Day_0_en","libraries.textcomposer_TextComposerVoiceNotEncrypted_Night_0_en",20420,], ["libraries.textcomposer_TextComposerVoice_Day_0_en","libraries.textcomposer_TextComposerVoice_Night_0_en",0,], ["libraries.designsystem.theme.components_TextDark_Text_en","",0,], -["libraries.designsystem.components.dialogs_TextFieldDialogWithError_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialogWithError_Night_0_en",20413,], -["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20413,], +["libraries.designsystem.components.dialogs_TextFieldDialogWithError_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialogWithError_Night_0_en",20420,], +["libraries.designsystem.components.dialogs_TextFieldDialog_Day_0_en","libraries.designsystem.components.dialogs_TextFieldDialog_Night_0_en",20420,], ["libraries.designsystem.components.list_TextFieldListItemEmpty_Text_field_List_item_-_empty_List_items_en","",0,], ["libraries.designsystem.components.list_TextFieldListItemTextFieldValue_Text_field_List_item_-_textfieldvalue_List_items_en","",0,], ["libraries.designsystem.components.list_TextFieldListItem_Text_field_List_item_-_text_List_items_en","",0,], @@ -1284,16 +1301,16 @@ export const screenshots = [ ["libraries.mediaviewer.impl.local.txt_TextFileContentView_Day_3_en","libraries.mediaviewer.impl.local.txt_TextFileContentView_Night_3_en",0,], ["libraries.textcomposer.components_TextFormatting_Day_0_en","libraries.textcomposer.components_TextFormatting_Night_0_en",0,], ["libraries.designsystem.theme.components_TextLight_Text_en","",0,], -["features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en","features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en",20413,], -["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20413,], -["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20413,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20413,], -["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20413,], +["features.messages.impl.timeline.components_ThreadSummaryView_Day_0_en","features.messages.impl.timeline.components_ThreadSummaryView_Night_0_en",20420,], +["features.messages.impl.topbars_ThreadTopBar_Day_0_en","features.messages.impl.topbars_ThreadTopBar_Night_0_en",20420,], +["libraries.designsystem.theme.components.previews_TimePickerHorizontal_DateTime_pickers_en","",20420,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalDark_DateTime_pickers_en","",20420,], +["libraries.designsystem.theme.components.previews_TimePickerVerticalLight_DateTime_pickers_en","",20420,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_0_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_1_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_2_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_2_en",0,], -["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_3_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_3_en",20413,], -["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20413,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_3_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_3_en",20420,], +["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_4_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_4_en",20420,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_5_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_5_en",0,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_6_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_6_en",0,], ["features.messages.impl.timeline.components_TimelineEventTimestampView_Day_7_en","features.messages.impl.timeline.components_TimelineEventTimestampView_Night_7_en",0,], @@ -1303,18 +1320,18 @@ export const screenshots = [ ["features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_2_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_3_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemAudioView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemAudioView_Night_4_en",0,], -["features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en","features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en",20413,], +["features.messages.impl.timeline.components_TimelineItemCallNotifyView_Day_0_en","features.messages.impl.timeline.components_TimelineItemCallNotifyView_Night_0_en",20420,], ["features.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_Night_0_en",0,], ["features.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_Day_1_en","features.messages.impl.timeline.components.virtual_TimelineItemDaySeparatorView_Night_1_en",0,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_0_en",20413,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20413,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20413,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20413,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20413,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20413,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20413,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20413,], -["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_0_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_1_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_2_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_3_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_4_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_5_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_6_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_6_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_7_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_7_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Day_8_en","features.messages.impl.timeline.components.event_TimelineItemEncryptedView_Night_8_en",20420,], ["features.messages.impl.timeline.components_TimelineItemEventRowDisambiguated_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowDisambiguated_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowForDirectRoom_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowForDirectRoom_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowLongSenderName_en","",0,], @@ -1322,18 +1339,18 @@ export const screenshots = [ ["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_2_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_2_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_3_en",20413,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20413,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_3_en",20420,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_4_en",20420,], ["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_5_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_5_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_6_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_6_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_7_en",20413,], -["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20413,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20413,], +["features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowTimestamp_Night_7_en",20420,], +["features.messages.impl.timeline.components_TimelineItemEventRowUtd_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowUtd_Night_0_en",20420,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithManyReactions_Night_0_en",20420,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Day_2_en","features.messages.impl.timeline.components_TimelineItemEventRowWithRR_Night_2_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en",20413,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20413,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_0_en",20420,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyInformative_Night_1_en",20420,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Night_0_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReplyOther_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_0_en",0,], @@ -1342,41 +1359,41 @@ export const screenshots = [ ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_1_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_1_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_2_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_2_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_3_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_3_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20413,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_4_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_4_en",20420,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_5_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_5_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_6_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_6_en",0,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_7_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_7_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en",20413,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_8_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_8_en",20420,], ["features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Day_9_en","features.messages.impl.timeline.components_TimelineItemEventRowWithReply_Night_9_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en",20413,], +["features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRowWithThreadSummary_Night_0_en",20420,], ["features.messages.impl.timeline.components_TimelineItemEventRow_Day_0_en","features.messages.impl.timeline.components_TimelineItemEventRow_Night_0_en",0,], -["features.messages.impl.timeline.components_TimelineItemEventTimestampBelow_en","",20413,], +["features.messages.impl.timeline.components_TimelineItemEventTimestampBelow_en","",20420,], ["features.messages.impl.timeline.components.event_TimelineItemFileView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemFileView_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemFileView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemFileView_Night_1_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemFileView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemFileView_Night_2_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemFileView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemFileView_Night_3_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemFileView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemFileView_Night_4_en",0,], -["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Night_0_en",20413,], -["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20413,], -["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20413,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentCollapse_Night_0_en",20420,], +["features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Day_0_en","features.messages.impl.timeline.components_TimelineItemGroupedEventsRowContentExpanded_Night_0_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageViewHideMediaContent_Night_0_en",20420,], ["features.messages.impl.timeline.components.event_TimelineItemImageView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemImageView_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemImageView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemImageView_Night_1_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemImageView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemImageView_Night_2_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemImageView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemImageView_Night_3_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemInformativeView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemInformativeView_Night_0_en",0,], -["features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Night_0_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLegacyCallInviteView_Night_0_en",20420,], ["features.messages.impl.timeline.components.event_TimelineItemLocationView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemLocationView_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemLocationView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemLocationView_Night_1_en",0,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_0_en",20413,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20413,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20413,], -["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20413,], -["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_0_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_1_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_2_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemPollView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemPollView_Night_3_en",20420,], +["features.messages.impl.timeline.components_TimelineItemReactionsLayout_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsLayout_Night_0_en",20420,], ["features.messages.impl.timeline.components_TimelineItemReactionsViewFew_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewFew_Night_0_en",0,], -["features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Night_0_en",20413,], -["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20413,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewIncoming_Night_0_en",20420,], +["features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsViewOutgoing_Night_0_en",20420,], ["features.messages.impl.timeline.components_TimelineItemReactionsView_Day_0_en","features.messages.impl.timeline.components_TimelineItemReactionsView_Night_0_en",0,], -["features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Night_0_en",20413,], +["features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemReadMarkerView_Night_0_en",20420,], ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_0_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_0_en",0,], ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_1_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_1_en",0,], ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_2_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_2_en",0,], @@ -1385,8 +1402,8 @@ export const screenshots = [ ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_5_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_5_en",0,], ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_6_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_6_en",0,], ["features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Day_7_en","features.messages.impl.timeline.components.receipt_TimelineItemReadReceiptView_Night_7_en",0,], -["features.messages.impl.timeline.components.event_TimelineItemRedactedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemRedactedView_Night_0_en",20413,], -["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemRedactedView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemRedactedView_Night_0_en",20420,], +["features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineItemRoomBeginningView_Night_0_en",20420,], ["features.messages.impl.timeline.components_TimelineItemStateEventRow_Day_0_en","features.messages.impl.timeline.components_TimelineItemStateEventRow_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemStateView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemStateView_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemStickerView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemStickerView_Night_0_en",0,], @@ -1401,8 +1418,8 @@ export const screenshots = [ ["features.messages.impl.timeline.components.event_TimelineItemTextView_Day_3_en","features.messages.impl.timeline.components.event_TimelineItemTextView_Night_3_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemTextView_Day_4_en","features.messages.impl.timeline.components.event_TimelineItemTextView_Night_4_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemTextView_Day_5_en","features.messages.impl.timeline.components.event_TimelineItemTextView_Night_5_en",0,], -["features.messages.impl.timeline.components.event_TimelineItemUnknownView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemUnknownView_Night_0_en",20413,], -["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20413,], +["features.messages.impl.timeline.components.event_TimelineItemUnknownView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemUnknownView_Night_0_en",20420,], +["features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoViewHideMediaContent_Night_0_en",20420,], ["features.messages.impl.timeline.components.event_TimelineItemVideoView_Day_0_en","features.messages.impl.timeline.components.event_TimelineItemVideoView_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemVideoView_Day_1_en","features.messages.impl.timeline.components.event_TimelineItemVideoView_Night_1_en",0,], ["features.messages.impl.timeline.components.event_TimelineItemVideoView_Day_2_en","features.messages.impl.timeline.components.event_TimelineItemVideoView_Night_2_en",0,], @@ -1425,85 +1442,85 @@ export const screenshots = [ ["features.messages.impl.timeline.components.event_TimelineItemVoiceView_Day_9_en","features.messages.impl.timeline.components.event_TimelineItemVoiceView_Night_9_en",0,], ["features.messages.impl.timeline.components.virtual_TimelineLoadingMoreIndicator_Day_0_en","features.messages.impl.timeline.components.virtual_TimelineLoadingMoreIndicator_Night_0_en",0,], ["features.messages.impl.timeline.components.event_TimelineVideoWithCaptionRow_Day_0_en","features.messages.impl.timeline.components.event_TimelineVideoWithCaptionRow_Night_0_en",0,], -["features.messages.impl.timeline_TimelineViewMessageShield_Day_0_en","features.messages.impl.timeline_TimelineViewMessageShield_Night_0_en",20413,], -["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20413,], +["features.messages.impl.timeline_TimelineViewMessageShield_Day_0_en","features.messages.impl.timeline_TimelineViewMessageShield_Night_0_en",20420,], +["features.messages.impl.timeline_TimelineView_Day_0_en","features.messages.impl.timeline_TimelineView_Night_0_en",20420,], ["features.messages.impl.timeline_TimelineView_Day_10_en","features.messages.impl.timeline_TimelineView_Night_10_en",0,], -["features.messages.impl.timeline_TimelineView_Day_11_en","features.messages.impl.timeline_TimelineView_Night_11_en",20413,], -["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20413,], -["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20413,], -["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20413,], -["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20413,], -["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20413,], -["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20413,], -["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20413,], +["features.messages.impl.timeline_TimelineView_Day_11_en","features.messages.impl.timeline_TimelineView_Night_11_en",20420,], +["features.messages.impl.timeline_TimelineView_Day_12_en","features.messages.impl.timeline_TimelineView_Night_12_en",20420,], +["features.messages.impl.timeline_TimelineView_Day_13_en","features.messages.impl.timeline_TimelineView_Night_13_en",20420,], +["features.messages.impl.timeline_TimelineView_Day_14_en","features.messages.impl.timeline_TimelineView_Night_14_en",20420,], +["features.messages.impl.timeline_TimelineView_Day_15_en","features.messages.impl.timeline_TimelineView_Night_15_en",20420,], +["features.messages.impl.timeline_TimelineView_Day_16_en","features.messages.impl.timeline_TimelineView_Night_16_en",20420,], +["features.messages.impl.timeline_TimelineView_Day_17_en","features.messages.impl.timeline_TimelineView_Night_17_en",20420,], +["features.messages.impl.timeline_TimelineView_Day_1_en","features.messages.impl.timeline_TimelineView_Night_1_en",20420,], ["features.messages.impl.timeline_TimelineView_Day_2_en","features.messages.impl.timeline_TimelineView_Night_2_en",0,], ["features.messages.impl.timeline_TimelineView_Day_3_en","features.messages.impl.timeline_TimelineView_Night_3_en",0,], -["features.messages.impl.timeline_TimelineView_Day_4_en","features.messages.impl.timeline_TimelineView_Night_4_en",20413,], +["features.messages.impl.timeline_TimelineView_Day_4_en","features.messages.impl.timeline_TimelineView_Night_4_en",20420,], ["features.messages.impl.timeline_TimelineView_Day_5_en","features.messages.impl.timeline_TimelineView_Night_5_en",0,], -["features.messages.impl.timeline_TimelineView_Day_6_en","features.messages.impl.timeline_TimelineView_Night_6_en",20413,], +["features.messages.impl.timeline_TimelineView_Day_6_en","features.messages.impl.timeline_TimelineView_Night_6_en",20420,], ["features.messages.impl.timeline_TimelineView_Day_7_en","features.messages.impl.timeline_TimelineView_Night_7_en",0,], -["features.messages.impl.timeline_TimelineView_Day_8_en","features.messages.impl.timeline_TimelineView_Night_8_en",20413,], +["features.messages.impl.timeline_TimelineView_Day_8_en","features.messages.impl.timeline_TimelineView_Night_8_en",20420,], ["features.messages.impl.timeline_TimelineView_Day_9_en","features.messages.impl.timeline_TimelineView_Night_9_en",0,], ["libraries.designsystem.components.avatar.internal_TombstonedRoomAvatar_Avatars_en","",0,], ["libraries.designsystem.theme.components_TopAppBarStr_App_Bars_en","",0,], ["libraries.designsystem.theme.components_TopAppBar_App_Bars_en","",0,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_0_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_0_en",20413,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20413,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20413,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20413,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20413,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20413,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20413,], -["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20413,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_0_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_0_en",20420,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_1_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_1_en",20420,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_2_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_2_en",20420,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_3_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_3_en",20420,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_4_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_4_en",20420,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_5_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_5_en",20420,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_6_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_6_en",20420,], +["libraries.troubleshoot.impl_TroubleshootNotificationsView_Day_7_en","libraries.troubleshoot.impl_TroubleshootNotificationsView_Night_7_en",20420,], ["features.messages.impl.typing_TypingNotificationView_Day_0_en","features.messages.impl.typing_TypingNotificationView_Night_0_en",0,], -["features.messages.impl.typing_TypingNotificationView_Day_1_en","features.messages.impl.typing_TypingNotificationView_Night_1_en",20413,], -["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20413,], -["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20413,], -["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20413,], -["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20413,], -["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20413,], +["features.messages.impl.typing_TypingNotificationView_Day_1_en","features.messages.impl.typing_TypingNotificationView_Night_1_en",20420,], +["features.messages.impl.typing_TypingNotificationView_Day_2_en","features.messages.impl.typing_TypingNotificationView_Night_2_en",20420,], +["features.messages.impl.typing_TypingNotificationView_Day_3_en","features.messages.impl.typing_TypingNotificationView_Night_3_en",20420,], +["features.messages.impl.typing_TypingNotificationView_Day_4_en","features.messages.impl.typing_TypingNotificationView_Night_4_en",20420,], +["features.messages.impl.typing_TypingNotificationView_Day_5_en","features.messages.impl.typing_TypingNotificationView_Night_5_en",20420,], +["features.messages.impl.typing_TypingNotificationView_Day_6_en","features.messages.impl.typing_TypingNotificationView_Night_6_en",20420,], ["features.messages.impl.typing_TypingNotificationView_Day_7_en","features.messages.impl.typing_TypingNotificationView_Night_7_en",0,], ["features.messages.impl.typing_TypingNotificationView_Day_8_en","features.messages.impl.typing_TypingNotificationView_Night_8_en",0,], ["libraries.designsystem.atomic.atoms_UnreadIndicatorAtom_Day_0_en","libraries.designsystem.atomic.atoms_UnreadIndicatorAtom_Night_0_en",0,], -["libraries.matrix.ui.components_UnresolvedUserRow_en","",20413,], +["libraries.matrix.ui.components_UnresolvedUserRow_en","",20420,], ["libraries.matrix.ui.components_UnsavedAvatar_Day_0_en","libraries.matrix.ui.components_UnsavedAvatar_Night_0_en",0,], ["libraries.designsystem.components.avatar.internal_UserAvatarColors_Day_0_en","libraries.designsystem.components.avatar.internal_UserAvatarColors_Night_0_en",0,], -["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20413,], -["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20413,], -["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20413,], -["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20413,], +["features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Day_0_en","features.roomdetails.impl.notificationsettings_UserDefinedRoomNotificationSettingsView_Night_0_en",20420,], +["features.startchat.impl.components_UserListView_Day_0_en","features.startchat.impl.components_UserListView_Night_0_en",20420,], +["features.startchat.impl.components_UserListView_Day_1_en","features.startchat.impl.components_UserListView_Night_1_en",20420,], +["features.startchat.impl.components_UserListView_Day_2_en","features.startchat.impl.components_UserListView_Night_2_en",20420,], ["features.startchat.impl.components_UserListView_Day_3_en","features.startchat.impl.components_UserListView_Night_3_en",0,], ["features.startchat.impl.components_UserListView_Day_4_en","features.startchat.impl.components_UserListView_Night_4_en",0,], ["features.startchat.impl.components_UserListView_Day_5_en","features.startchat.impl.components_UserListView_Night_5_en",0,], ["features.startchat.impl.components_UserListView_Day_6_en","features.startchat.impl.components_UserListView_Night_6_en",0,], -["features.startchat.impl.components_UserListView_Day_7_en","features.startchat.impl.components_UserListView_Night_7_en",20413,], +["features.startchat.impl.components_UserListView_Day_7_en","features.startchat.impl.components_UserListView_Night_7_en",20420,], ["features.startchat.impl.components_UserListView_Day_8_en","features.startchat.impl.components_UserListView_Night_8_en",0,], -["features.startchat.impl.components_UserListView_Day_9_en","features.startchat.impl.components_UserListView_Night_9_en",20413,], +["features.startchat.impl.components_UserListView_Day_9_en","features.startchat.impl.components_UserListView_Night_9_en",20420,], ["features.preferences.impl.user_UserPreferences_Day_0_en","features.preferences.impl.user_UserPreferences_Night_0_en",0,], ["features.preferences.impl.user_UserPreferences_Day_1_en","features.preferences.impl.user_UserPreferences_Night_1_en",0,], ["features.preferences.impl.user_UserPreferences_Day_2_en","features.preferences.impl.user_UserPreferences_Night_2_en",0,], -["features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Day_0_en","features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Night_0_en",20413,], -["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20413,], -["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20413,], -["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20413,], -["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20413,], -["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20413,], -["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20413,], -["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20413,], -["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20413,], -["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20413,], -["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20413,], -["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20413,], +["features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Day_0_en","features.userprofile.shared_UserProfileHeaderSectionWithVerificationViolation_Night_0_en",20420,], +["features.userprofile.shared_UserProfileHeaderSection_Day_0_en","features.userprofile.shared_UserProfileHeaderSection_Night_0_en",20420,], +["features.userprofile.shared_UserProfileView_Day_0_en","features.userprofile.shared_UserProfileView_Night_0_en",20420,], +["features.userprofile.shared_UserProfileView_Day_1_en","features.userprofile.shared_UserProfileView_Night_1_en",20420,], +["features.userprofile.shared_UserProfileView_Day_2_en","features.userprofile.shared_UserProfileView_Night_2_en",20420,], +["features.userprofile.shared_UserProfileView_Day_3_en","features.userprofile.shared_UserProfileView_Night_3_en",20420,], +["features.userprofile.shared_UserProfileView_Day_4_en","features.userprofile.shared_UserProfileView_Night_4_en",20420,], +["features.userprofile.shared_UserProfileView_Day_5_en","features.userprofile.shared_UserProfileView_Night_5_en",20420,], +["features.userprofile.shared_UserProfileView_Day_6_en","features.userprofile.shared_UserProfileView_Night_6_en",20420,], +["features.userprofile.shared_UserProfileView_Day_7_en","features.userprofile.shared_UserProfileView_Night_7_en",20420,], +["features.userprofile.shared_UserProfileView_Day_8_en","features.userprofile.shared_UserProfileView_Night_8_en",20420,], +["features.userprofile.shared_UserProfileView_Day_9_en","features.userprofile.shared_UserProfileView_Night_9_en",20420,], ["features.verifysession.impl.ui_VerificationUserProfileContent_Day_0_en","features.verifysession.impl.ui_VerificationUserProfileContent_Night_0_en",0,], ["libraries.designsystem.ruler_VerticalRuler_Day_0_en","libraries.designsystem.ruler_VerticalRuler_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_0_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_0_en",0,], ["libraries.mediaviewer.impl.gallery.ui_VideoItemView_Day_1_en","libraries.mediaviewer.impl.gallery.ui_VideoItemView_Night_1_en",0,], -["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20413,], -["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20413,], +["features.preferences.impl.advanced_VideoQualitySelectorDialog_Day_0_en","features.preferences.impl.advanced_VideoQualitySelectorDialog_Night_0_en",20420,], +["features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Day_0_en","features.messages.impl.attachments.preview_VideoQualitySelectorDialog_Night_0_en",20420,], ["features.viewfolder.impl.file_ViewFileView_Day_0_en","features.viewfolder.impl.file_ViewFileView_Night_0_en",0,], ["features.viewfolder.impl.file_ViewFileView_Day_1_en","features.viewfolder.impl.file_ViewFileView_Night_1_en",0,], ["features.viewfolder.impl.file_ViewFileView_Day_2_en","features.viewfolder.impl.file_ViewFileView_Night_2_en",0,], -["features.viewfolder.impl.file_ViewFileView_Day_3_en","features.viewfolder.impl.file_ViewFileView_Night_3_en",20413,], +["features.viewfolder.impl.file_ViewFileView_Day_3_en","features.viewfolder.impl.file_ViewFileView_Night_3_en",20420,], ["features.viewfolder.impl.file_ViewFileView_Day_4_en","features.viewfolder.impl.file_ViewFileView_Night_4_en",0,], ["features.viewfolder.impl.file_ViewFileView_Day_5_en","features.viewfolder.impl.file_ViewFileView_Night_5_en",0,], ["features.viewfolder.impl.folder_ViewFolderView_Day_0_en","features.viewfolder.impl.folder_ViewFolderView_Night_0_en",0,], From eedaeb6b3547a6811cd2bd3d2e48cc6fa56282c4 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Dec 2025 13:35:11 +0000 Subject: [PATCH 101/113] fix(deps): update dependency com.posthog:posthog-android to v3.27.0 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1a8ebd36a2..95b431d67d 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -216,7 +216,7 @@ haze_materials = { module = "dev.chrisbanes.haze:haze-materials", version.ref = color_picker = "io.mhssn:colorpicker:1.0.0" # Analytics -posthog = "com.posthog:posthog-android:3.26.0" +posthog = "com.posthog:posthog-android:3.27.0" sentry = "io.sentry:sentry-android:8.27.1" # main branch can be tested replacing the version with main-SNAPSHOT matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.29.2" From 2e2d68ba83044f359718b466ea26026a23b7f7bd Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Tue, 2 Dec 2025 16:22:55 +0100 Subject: [PATCH 102/113] Load `JoinedRoom` in home screen, pass it to the room flow (#5817) * Load `JoinedRoom` in `HomeFlowNode.navigateToRoom`, then pass it to the next navigation nodes * Add delayed loading indicator for cases when loading the room takes too long * Avoid an extra FFI call in `RustRoomFactory`. Use `RoomInfo.membership` instead. Also use `computation` dispatcher, since it should reduce the delay when switching contexts. * Remove the dispatcher usage when loading the room in `HomeFlowNode`, we immediately call a method that changes the dispatcher used * Make sure only a single room is opened at a time --- .../android/appnav/LoggedInFlowNode.kt | 20 ++++-- .../android/appnav/room/RoomFlowNode.kt | 39 ++++++++--- .../appnav/room/RoomNavigationTarget.kt | 3 + .../appnav/room/joined/JoinedRoomFlowNode.kt | 4 +- .../LoadingBaseRoomStateFlowFactoryTest.kt | 19 ++++- .../features/home/api/HomeEntryPoint.kt | 3 +- .../features/home/impl/HomeFlowNode.kt | 69 ++++++++++++++++++- .../home/impl/DefaultHomeEntryPointTest.kt | 7 +- .../impl/timeline/TimelinePresenter.kt | 2 + .../matrix/impl/room/RustRoomFactory.kt | 38 +++++----- .../matrix/ui/room/LoadingRoomState.kt | 24 ++++--- tests/uitests/build.gradle.kts | 5 ++ 12 files changed, 180 insertions(+), 53 deletions(-) diff --git a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt index 7e782c7cc4..38dc39ee83 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/LoggedInFlowNode.kt @@ -39,7 +39,6 @@ import com.bumble.appyx.navmodel.backstack.operation.replace import com.bumble.appyx.navmodel.backstack.operation.singleTop import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject -import im.vector.app.features.analytics.plan.JoinedRoom import io.element.android.annotations.ContributesNode import io.element.android.appnav.loggedin.LoggedInNode import io.element.android.appnav.loggedin.MediaPreviewConfigMigration @@ -84,6 +83,7 @@ import io.element.android.libraries.matrix.api.core.RoomIdOrAlias import io.element.android.libraries.matrix.api.core.UserId import io.element.android.libraries.matrix.api.core.toRoomIdOrAlias import io.element.android.libraries.matrix.api.permalink.PermalinkData +import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.api.sync.SyncService import io.element.android.libraries.matrix.api.verification.SessionVerificationServiceListener import io.element.android.libraries.matrix.api.verification.VerificationRequest @@ -109,6 +109,7 @@ import java.util.UUID import kotlin.time.Duration.Companion.minutes import kotlin.time.Duration.Companion.seconds import kotlin.time.toKotlinDuration +import im.vector.app.features.analytics.plan.JoinedRoom as JoinedRoomAnalyticsEvent @ContributesNode(SessionScope::class) @AssistedInject @@ -265,7 +266,7 @@ class LoggedInFlowNode( data class Room( val roomIdOrAlias: RoomIdOrAlias, val serverNames: List = emptyList(), - val trigger: JoinedRoom.Trigger? = null, + val trigger: JoinedRoomAnalyticsEvent.Trigger? = null, val roomDescription: RoomDescription? = null, val initialElement: RoomNavigationTarget = RoomNavigationTarget.Root(), val targetId: UUID = UUID.randomUUID(), @@ -315,8 +316,13 @@ class LoggedInFlowNode( } NavTarget.Home -> { val callback = object : HomeEntryPoint.Callback { - override fun navigateToRoom(roomId: RoomId) { - backstack.push(NavTarget.Room(roomId.toRoomIdOrAlias())) + override fun navigateToRoom(roomId: RoomId, joinedRoom: JoinedRoom?) { + backstack.push( + NavTarget.Room( + roomIdOrAlias = roomId.toRoomIdOrAlias(), + initialElement = RoomNavigationTarget.Root(joinedRoom = joinedRoom) + ) + ) } override fun navigateToSettings() { @@ -365,7 +371,7 @@ class LoggedInFlowNode( val target = NavTarget.Room( roomIdOrAlias = data.roomIdOrAlias, serverNames = data.viaParameters, - trigger = JoinedRoom.Trigger.Timeline, + trigger = JoinedRoomAnalyticsEvent.Trigger.Timeline, initialElement = RoomNavigationTarget.Root(data.eventId), ) if (pushToBackstack) { @@ -479,7 +485,7 @@ class LoggedInFlowNode( NavTarget.Room( roomIdOrAlias = roomDescription.roomId.toRoomIdOrAlias(), roomDescription = roomDescription, - trigger = JoinedRoom.Trigger.RoomDirectory, + trigger = JoinedRoomAnalyticsEvent.Trigger.RoomDirectory, ) ) } @@ -519,7 +525,7 @@ class LoggedInFlowNode( suspend fun attachRoom( roomIdOrAlias: RoomIdOrAlias, serverNames: List = emptyList(), - trigger: JoinedRoom.Trigger? = null, + trigger: JoinedRoomAnalyticsEvent.Trigger? = null, eventId: EventId? = null, clearBackstack: Boolean, ): RoomFlowNode { diff --git a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt index 9aa62d6b16..1bf3516900 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomFlowNode.kt @@ -19,10 +19,10 @@ import com.bumble.appyx.core.node.node import com.bumble.appyx.core.plugin.Plugin import com.bumble.appyx.core.plugin.plugins import com.bumble.appyx.navmodel.backstack.BackStack +import com.bumble.appyx.navmodel.backstack.active import com.bumble.appyx.navmodel.backstack.operation.newRoot import dev.zacsweers.metro.Assisted import dev.zacsweers.metro.AssistedInject -import im.vector.app.features.analytics.plan.JoinedRoom import io.element.android.annotations.ContributesNode import io.element.android.appnav.room.joined.JoinedRoomFlowNode import io.element.android.appnav.room.joined.JoinedRoomLoadedFlowNode @@ -60,10 +60,13 @@ import kotlinx.coroutines.flow.map import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.flow.shareIn import kotlinx.coroutines.launch +import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parcelize import timber.log.Timber import java.util.Optional import kotlin.jvm.optionals.getOrNull +import im.vector.app.features.analytics.plan.JoinedRoom as JoinedRoomAnalyticsEvent +import io.element.android.libraries.matrix.api.room.JoinedRoom as JoinedRoomInstance @ContributesNode(SessionScope::class) @AssistedInject @@ -77,7 +80,14 @@ class RoomFlowNode( private val analyticsService: AnalyticsService, ) : BaseFlowNode( backstack = BackStack( - initialElement = NavTarget.Loading, + initialElement = run { + val joinedRoom = (plugins.filterIsInstance().first().initialElement as? RoomNavigationTarget.Root)?.joinedRoom + if (joinedRoom != null) { + NavTarget.JoinedRoom(joinedRoom) + } else { + NavTarget.Loading + } + }, savedStateMap = buildContext.savedStateMap, ), buildContext = buildContext, @@ -87,7 +97,7 @@ class RoomFlowNode( val roomIdOrAlias: RoomIdOrAlias, val roomDescription: Optional, val serverNames: List, - val trigger: Optional, + val trigger: Optional, val initialElement: RoomNavigationTarget, ) : NodeInputs @@ -104,11 +114,16 @@ class RoomFlowNode( data class JoinRoom( val roomId: RoomId, val serverNames: List, - val trigger: im.vector.app.features.analytics.plan.JoinedRoom.Trigger, + val trigger: JoinedRoomAnalyticsEvent.Trigger, ) : NavTarget @Parcelize - data class JoinedRoom(val roomId: RoomId) : NavTarget + data class JoinedRoom( + val roomId: RoomId, + @IgnoredOnParcel val joinedRoom: JoinedRoomInstance? = null, + ) : NavTarget { + constructor(joinedRoom: JoinedRoomInstance) : this(joinedRoom.roomId, joinedRoom) + } } override fun onBuilt() { @@ -133,7 +148,9 @@ class RoomFlowNode( } private fun subscribeToRoomInfoFlow(roomId: RoomId, serverNames: List) { - val roomInfoFlow = client.getRoomInfoFlow(roomId) + val joinedRoom = (inputs.initialElement as? RoomNavigationTarget.Root)?.joinedRoom + val roomInfoFlow = joinedRoom?.roomInfoFlow?.map { Optional.of(it) } + ?: client.getRoomInfoFlow(roomId) // This observes the local membership changes for the room val membershipUpdateFlow = membershipObserver.updates @@ -149,6 +166,11 @@ class RoomFlowNode( currentMembershipFlow.onEach { (previousMembership, membership) -> Timber.d("Room membership: $membership") if (membership == CurrentUserMembership.JOINED) { + val currentNavTarget = backstack.active?.key?.navTarget + if (currentNavTarget is NavTarget.JoinedRoom && currentNavTarget.roomId == roomId) { + Timber.d("Already in JoinedRoom $roomId, do nothing") + return@onEach + } backstack.newRoot(NavTarget.JoinedRoom(roomId)) } else { val leavingFromCurrentDevice = @@ -163,7 +185,7 @@ class RoomFlowNode( NavTarget.JoinRoom( roomId = roomId, serverNames = serverNames, - trigger = inputs.trigger.getOrNull() ?: JoinedRoom.Trigger.Invite, + trigger = inputs.trigger.getOrNull() ?: JoinedRoomAnalyticsEvent.Trigger.Invite, ) ) } @@ -209,7 +231,8 @@ class RoomFlowNode( val roomFlowNodeCallback = plugins() val inputs = JoinedRoomFlowNode.Inputs( roomId = navTarget.roomId, - initialElement = inputs.initialElement + initialElement = inputs.initialElement, + joinedRoom = navTarget.joinedRoom, ) createNode(buildContext, plugins = listOf(inputs) + roomFlowNodeCallback) } diff --git a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomNavigationTarget.kt b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomNavigationTarget.kt index 93403371c9..aac916ab9d 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/room/RoomNavigationTarget.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/room/RoomNavigationTarget.kt @@ -10,12 +10,15 @@ package io.element.android.appnav.room import android.os.Parcelable import io.element.android.libraries.matrix.api.core.EventId +import io.element.android.libraries.matrix.api.room.JoinedRoom +import kotlinx.parcelize.IgnoredOnParcel import kotlinx.parcelize.Parcelize sealed interface RoomNavigationTarget : Parcelable { @Parcelize data class Root( val eventId: EventId? = null, + @IgnoredOnParcel val joinedRoom: JoinedRoom? = null, ) : RoomNavigationTarget @Parcelize diff --git a/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomFlowNode.kt b/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomFlowNode.kt index 85710deffe..504bdfec58 100644 --- a/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomFlowNode.kt +++ b/appnav/src/main/kotlin/io/element/android/appnav/room/joined/JoinedRoomFlowNode.kt @@ -38,6 +38,7 @@ import io.element.android.libraries.di.SessionScope import io.element.android.libraries.matrix.api.core.EventId import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.core.ThreadId +import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.ui.room.LoadingRoomState import io.element.android.libraries.matrix.ui.room.LoadingRoomStateFlowFactory import kotlinx.coroutines.flow.distinctUntilChanged @@ -63,11 +64,12 @@ class JoinedRoomFlowNode( ) { data class Inputs( val roomId: RoomId, + val joinedRoom: JoinedRoom?, val initialElement: RoomNavigationTarget, ) : NodeInputs private val inputs: Inputs = inputs() - private val loadingRoomStateStateFlow = loadingRoomStateFlowFactory.create(lifecycleScope, inputs.roomId) + private val loadingRoomStateStateFlow = loadingRoomStateFlowFactory.create(lifecycleScope, inputs.roomId, inputs.joinedRoom) sealed interface NavTarget : Parcelable { @Parcelize diff --git a/appnav/src/test/kotlin/io/element/android/appnav/room/LoadingBaseRoomStateFlowFactoryTest.kt b/appnav/src/test/kotlin/io/element/android/appnav/room/LoadingBaseRoomStateFlowFactoryTest.kt index c8810dff92..14128ac33a 100644 --- a/appnav/src/test/kotlin/io/element/android/appnav/room/LoadingBaseRoomStateFlowFactoryTest.kt +++ b/appnav/src/test/kotlin/io/element/android/appnav/room/LoadingBaseRoomStateFlowFactoryTest.kt @@ -23,6 +23,19 @@ import kotlinx.coroutines.test.runTest import org.junit.Test class LoadingBaseRoomStateFlowFactoryTest { + @Test + fun `flow should emit only Loaded when we already pass a JoinedRoom`() = runTest { + val room = FakeJoinedRoom(baseRoom = FakeBaseRoom(sessionId = A_SESSION_ID, roomId = A_ROOM_ID)) + val matrixClient = FakeMatrixClient(A_SESSION_ID) + val flowFactory = LoadingRoomStateFlowFactory(matrixClient) + flowFactory + .create(lifecycleScope = this, roomId = A_ROOM_ID, joinedRoom = room) + .test { + assertThat(awaitItem()).isEqualTo(LoadingRoomState.Loaded(room)) + ensureAllEventsConsumed() + } + } + @Test fun `flow should emit Loading and then Loaded when there is a room in cache`() = runTest { val room = FakeJoinedRoom(baseRoom = FakeBaseRoom(sessionId = A_SESSION_ID, roomId = A_ROOM_ID)) @@ -31,7 +44,7 @@ class LoadingBaseRoomStateFlowFactoryTest { } val flowFactory = LoadingRoomStateFlowFactory(matrixClient) flowFactory - .create(this, A_ROOM_ID) + .create(lifecycleScope = this, roomId = A_ROOM_ID, joinedRoom = null) .test { assertThat(awaitItem()).isEqualTo(LoadingRoomState.Loading) assertThat(awaitItem()).isEqualTo(LoadingRoomState.Loaded(room)) @@ -45,7 +58,7 @@ class LoadingBaseRoomStateFlowFactoryTest { val matrixClient = FakeMatrixClient(A_SESSION_ID, roomListService = roomListService) val flowFactory = LoadingRoomStateFlowFactory(matrixClient) flowFactory - .create(this, A_ROOM_ID) + .create(lifecycleScope = this, roomId = A_ROOM_ID, joinedRoom = null) .test { assertThat(awaitItem()).isEqualTo(LoadingRoomState.Loading) matrixClient.givenGetRoomResult(A_ROOM_ID, room) @@ -60,7 +73,7 @@ class LoadingBaseRoomStateFlowFactoryTest { val matrixClient = FakeMatrixClient(A_SESSION_ID, roomListService = roomListService) val flowFactory = LoadingRoomStateFlowFactory(matrixClient) flowFactory - .create(this, A_ROOM_ID) + .create(lifecycleScope = this, roomId = A_ROOM_ID, joinedRoom = null) .test { assertThat(awaitItem()).isEqualTo(LoadingRoomState.Loading) roomListService.postAllRoomsLoadingState(RoomList.LoadingState.Loaded(1)) diff --git a/features/home/api/src/main/kotlin/io/element/android/features/home/api/HomeEntryPoint.kt b/features/home/api/src/main/kotlin/io/element/android/features/home/api/HomeEntryPoint.kt index b3dd8f1ee1..71ee093985 100644 --- a/features/home/api/src/main/kotlin/io/element/android/features/home/api/HomeEntryPoint.kt +++ b/features/home/api/src/main/kotlin/io/element/android/features/home/api/HomeEntryPoint.kt @@ -13,6 +13,7 @@ import com.bumble.appyx.core.node.Node import com.bumble.appyx.core.plugin.Plugin import io.element.android.libraries.architecture.FeatureEntryPoint import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.room.JoinedRoom interface HomeEntryPoint : FeatureEntryPoint { fun createNode( @@ -22,7 +23,7 @@ interface HomeEntryPoint : FeatureEntryPoint { ): Node interface Callback : Plugin { - fun navigateToRoom(roomId: RoomId) + fun navigateToRoom(roomId: RoomId, joinedRoom: JoinedRoom?) fun navigateToCreateRoom() fun navigateToSettings() fun navigateToSetUpRecovery() diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt index 78e48fad79..d9f87e2edd 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/HomeFlowNode.kt @@ -14,6 +14,8 @@ import androidx.activity.compose.LocalActivity import androidx.compose.runtime.Composable import androidx.compose.runtime.collectAsState import androidx.compose.runtime.getValue +import androidx.compose.runtime.mutableStateOf +import androidx.compose.runtime.remember import androidx.compose.ui.Modifier import androidx.lifecycle.Lifecycle import androidx.lifecycle.coroutineScope @@ -41,20 +43,33 @@ import io.element.android.features.logout.api.direct.DirectLogoutView import io.element.android.features.reportroom.api.ReportRoomEntryPoint import io.element.android.features.rolesandpermissions.api.ChangeRoomMemberRolesEntryPoint import io.element.android.features.rolesandpermissions.api.ChangeRoomMemberRolesListType +import io.element.android.libraries.architecture.AsyncData import io.element.android.libraries.architecture.BackstackView import io.element.android.libraries.architecture.BaseFlowNode import io.element.android.libraries.architecture.appyx.launchMolecule import io.element.android.libraries.architecture.callback +import io.element.android.libraries.core.extensions.runCatchingExceptions import io.element.android.libraries.deeplink.api.usecase.InviteFriendsUseCase +import io.element.android.libraries.designsystem.components.ProgressDialog +import io.element.android.libraries.designsystem.utils.DelayedVisibility import io.element.android.libraries.di.SessionScope +import io.element.android.libraries.di.annotations.SessionCoroutineScope import io.element.android.libraries.matrix.api.MatrixClient import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.services.analytics.api.AnalyticsService +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job import kotlinx.coroutines.NonCancellable +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.job import kotlinx.coroutines.launch import kotlinx.coroutines.runBlocking import kotlinx.coroutines.withContext import kotlinx.parcelize.Parcelize +import timber.log.Timber +import kotlin.coroutines.cancellation.CancellationException +import kotlin.time.Duration.Companion.milliseconds @ContributesNode(SessionScope::class) @AssistedInject @@ -71,6 +86,7 @@ class HomeFlowNode( private val declineInviteAndBlockUserEntryPoint: DeclineInviteAndBlockEntryPoint, private val changeRoomMemberRolesEntryPoint: ChangeRoomMemberRolesEntryPoint, private val leaveRoomRenderer: LeaveRoomRenderer, + @SessionCoroutineScope private val sessionCoroutineScope: CoroutineScope, ) : BaseFlowNode( backstack = BackStack( initialElement = NavTarget.Root, @@ -150,9 +166,58 @@ class HomeFlowNode( return node(buildContext) { modifier -> val state by stateFlow.collectAsState() val activity = requireNotNull(LocalActivity.current) + + val loadingJoinedRoomJob = remember { mutableStateOf>(AsyncData.Uninitialized) } + if (loadingJoinedRoomJob.value.isLoading()) { + DelayedVisibility(duration = 400.milliseconds) { + ProgressDialog( + onDismissRequest = { + loadingJoinedRoomJob.value.dataOrNull()?.cancel() + loadingJoinedRoomJob.value = AsyncData.Uninitialized + } + ) + } + } + + fun navigateToRoom( + roomId: RoomId, + ) { + if (!loadingJoinedRoomJob.value.isUninitialized()) { + Timber.w("Already loading a room, ignoring navigateToRoom for $roomId") + return + } + + val job = sessionCoroutineScope.launch { + runCatchingExceptions { + matrixClient.getJoinedRoom(roomId) + }.fold( + onSuccess = { joinedRoom -> + if (isActive) { + callback.navigateToRoom(roomId, joinedRoom) + loadingJoinedRoomJob.value = AsyncData.Success(coroutineContext.job) + // Wait a bit before resetting the state to avoid allowing to open several rooms + delay(200.milliseconds) + loadingJoinedRoomJob.value = AsyncData.Uninitialized + } + }, + onFailure = { + // If the operation wasn't cancelled, navigate without the room, using the room id + if (it !is CancellationException) { + callback.navigateToRoom(roomId, null) + } + loadingJoinedRoomJob.value = AsyncData.Failure(error = it, prevData = coroutineContext.job) + // Wait a bit before resetting the state to avoid allowing to open several rooms + delay(200.milliseconds) + loadingJoinedRoomJob.value = AsyncData.Uninitialized + } + ) + } + loadingJoinedRoomJob.value = AsyncData.Loading(job) + } + HomeView( homeState = state, - onRoomClick = callback::navigateToRoom, + onRoomClick = ::navigateToRoom, onSettingsClick = callback::navigateToSettings, onStartChatClick = callback::navigateToCreateRoom, onSetUpRecoveryClick = callback::navigateToSetUpRecovery, @@ -165,7 +230,7 @@ class HomeFlowNode( acceptDeclineInviteView = { acceptDeclineInviteView.Render( state = state.roomListState.acceptDeclineInviteState, - onAcceptInviteSuccess = callback::navigateToRoom, + onAcceptInviteSuccess = ::navigateToRoom, onDeclineInviteSuccess = { }, modifier = Modifier ) diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt index ed6482b0e7..9778556dd2 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/DefaultHomeEntryPointTest.kt @@ -13,17 +13,19 @@ import com.bumble.appyx.core.modality.BuildContext import com.google.common.truth.Truth.assertThat import io.element.android.features.home.api.HomeEntryPoint import io.element.android.libraries.matrix.api.core.RoomId +import io.element.android.libraries.matrix.api.room.JoinedRoom import io.element.android.libraries.matrix.test.FakeMatrixClient import io.element.android.services.analytics.test.FakeAnalyticsService import io.element.android.tests.testutils.lambda.lambdaError import io.element.android.tests.testutils.node.TestParentNode +import kotlinx.coroutines.test.runTest import org.junit.Test import org.junit.runner.RunWith @RunWith(AndroidJUnit4::class) class DefaultHomeEntryPointTest { @Test - fun `test node builder`() { + fun `test node builder`() = runTest { val entryPoint = DefaultHomeEntryPoint() val parentNode = TestParentNode.create { buildContext, plugins -> HomeFlowNode( @@ -39,10 +41,11 @@ class DefaultHomeEntryPointTest { declineInviteAndBlockUserEntryPoint = { _, _, _ -> lambdaError() }, changeRoomMemberRolesEntryPoint = { _, _, _, _ -> lambdaError() }, leaveRoomRenderer = { _, _, _ -> lambdaError() }, + sessionCoroutineScope = backgroundScope, ) } val callback = object : HomeEntryPoint.Callback { - override fun navigateToRoom(roomId: RoomId) = lambdaError() + override fun navigateToRoom(roomId: RoomId, joinedRoom: JoinedRoom?) = lambdaError() override fun navigateToCreateRoom() = lambdaError() override fun navigateToSettings() = lambdaError() override fun navigateToSetUpRecovery() = lambdaError() diff --git a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt index 7b8ff837c1..e44cac4f27 100644 --- a/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt +++ b/features/messages/impl/src/main/kotlin/io/element/android/features/messages/impl/timeline/TimelinePresenter.kt @@ -65,6 +65,7 @@ import kotlinx.collections.immutable.persistentListOf import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.delay import kotlinx.coroutines.flow.combine +import kotlinx.coroutines.flow.flowOn import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch @@ -261,6 +262,7 @@ class TimelinePresenter( items } .onEach(redactedVoiceMessageManager::onEachMatrixTimelineItem) + .flowOn(dispatchers.computation) .launchIn(this) } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt index 5ff8e5d999..55498c150d 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt @@ -36,6 +36,7 @@ import kotlinx.coroutines.withContext import org.matrix.rustcomponents.sdk.DateDividerMode import org.matrix.rustcomponents.sdk.Membership import org.matrix.rustcomponents.sdk.Room +import org.matrix.rustcomponents.sdk.RoomInfo import org.matrix.rustcomponents.sdk.TimelineConfiguration import org.matrix.rustcomponents.sdk.TimelineFilter import org.matrix.rustcomponents.sdk.TimelineFocus @@ -60,7 +61,7 @@ class RustRoomFactory( private val roomInfoMapper: RoomInfoMapper, private val analyticsService: AnalyticsService, ) { - private val dispatcher = dispatchers.io.limitedParallelism(1) + private val dispatcher = dispatchers.computation.limitedParallelism(1) private val mutex = Mutex() private val isDestroyed: AtomicBoolean = AtomicBoolean(false) @@ -86,24 +87,21 @@ class RustRoomFactory( return@withContext null } val room = awaitRoomInRoomList(roomId) ?: return@withContext null - getBaseRoom(room) + getBaseRoom(sdkRoom = room, roomInfo = room.roomInfo()) } } - private suspend fun getBaseRoom(sdkRoom: Room): RustBaseRoom { - val initialRoomInfo = sdkRoom.roomInfo() - return RustBaseRoom( - sessionId = sessionId, - deviceId = deviceId, - innerRoom = sdkRoom, - coroutineDispatchers = dispatchers, - roomSyncSubscriber = roomSyncSubscriber, - roomMembershipObserver = roomMembershipObserver, - roomInfoMapper = roomInfoMapper, - initialRoomInfo = roomInfoMapper.map(initialRoomInfo), - sessionCoroutineScope = sessionCoroutineScope, - ) - } + private fun getBaseRoom(sdkRoom: Room, roomInfo: RoomInfo) = RustBaseRoom( + sessionId = sessionId, + deviceId = deviceId, + innerRoom = sdkRoom, + coroutineDispatchers = dispatchers, + roomSyncSubscriber = roomSyncSubscriber, + roomMembershipObserver = roomMembershipObserver, + roomInfoMapper = roomInfoMapper, + initialRoomInfo = roomInfoMapper.map(roomInfo), + sessionCoroutineScope = sessionCoroutineScope, + ) suspend fun getJoinedRoomOrPreview(roomId: RoomId, serverNames: List): GetRoomResult? = withContext(dispatcher) { mutex.withLock { @@ -113,10 +111,11 @@ class RustRoomFactory( } val sdkRoom = awaitRoomInRoomList(roomId) ?: return@withLock null + val roomInfo = sdkRoom.roomInfo() val parentTransaction = analyticsService.getLongRunningTransaction(AnalyticsLongRunningTransaction.OpenRoom) - if (sdkRoom.membership() == Membership.JOINED) { + if (roomInfo.membership == Membership.JOINED) { analyticsService.recordTransaction( name = "Get joined room", operation = "RustRoomFactory.getJoinedRoomOrPreview", @@ -140,10 +139,9 @@ class RustRoomFactory( ) } - val baseRoom = transaction.recordChildTransaction(operation = "getBaseRoom", description = "Get room from SDK") { getBaseRoom(sdkRoom) } GetRoomResult.Joined( JoinedRustRoom( - baseRoom = baseRoom, + baseRoom = getBaseRoom(sdkRoom, roomInfo), notificationSettingsService = notificationSettingsService, roomContentForwarder = roomContentForwarder, liveInnerTimeline = timeline, @@ -169,7 +167,7 @@ class RustRoomFactory( GetRoomResult.NotJoined( NotJoinedRustRoom( sessionId = sessionId, - localRoom = getBaseRoom(sdkRoom), + localRoom = getBaseRoom(sdkRoom, roomInfo), previewInfo = RoomPreviewInfoMapper.map(preview.info()), ) ) diff --git a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/LoadingRoomState.kt b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/LoadingRoomState.kt index 0b7c16b3a0..cbbe79b480 100644 --- a/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/LoadingRoomState.kt +++ b/libraries/matrixui/src/main/kotlin/io/element/android/libraries/matrix/ui/room/LoadingRoomState.kt @@ -16,6 +16,7 @@ import io.element.android.libraries.matrix.api.core.RoomId import io.element.android.libraries.matrix.api.room.JoinedRoom import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableStateFlow import kotlinx.coroutines.flow.SharingStarted import kotlinx.coroutines.flow.StateFlow import kotlinx.coroutines.flow.asFlow @@ -39,16 +40,21 @@ open class LoadingRoomStateProvider : PreviewParameterProvider @Inject class LoadingRoomStateFlowFactory(private val matrixClient: MatrixClient) { - fun create(lifecycleScope: CoroutineScope, roomId: RoomId): StateFlow = - getJoinedRoomFlow(roomId) - .map { room -> - if (room != null) { - LoadingRoomState.Loaded(room) - } else { - LoadingRoomState.Error + fun create(lifecycleScope: CoroutineScope, roomId: RoomId, joinedRoom: JoinedRoom?): StateFlow { + return if (joinedRoom != null) { + MutableStateFlow(LoadingRoomState.Loaded(joinedRoom)) + } else { + getJoinedRoomFlow(roomId) + .map { room -> + if (room != null) { + LoadingRoomState.Loaded(room) + } else { + LoadingRoomState.Error + } } - } - .stateIn(lifecycleScope, SharingStarted.Eagerly, LoadingRoomState.Loading) + .stateIn(lifecycleScope, SharingStarted.Eagerly, LoadingRoomState.Loading) + } + } private fun getJoinedRoomFlow(roomId: RoomId): Flow = suspend { matrixClient.getJoinedRoom(roomId = roomId) diff --git a/tests/uitests/build.gradle.kts b/tests/uitests/build.gradle.kts index ea43284476..53876b0c8c 100644 --- a/tests/uitests/build.gradle.kts +++ b/tests/uitests/build.gradle.kts @@ -20,6 +20,11 @@ android { namespace = "ui" } +tasks.withType(Test::class.java) { + // Don't fail the test run if there are no tests, this can happen if we run them with screenshot test disabled + failOnNoDiscoveredTests = false +} + dependencies { // Paparazzi 1.3.2 workaround (see https://github.com/cashapp/paparazzi/blob/master/CHANGELOG.md#132---2024-01-13) constraints.add("testImplementation", "com.google.guava:guava") { From 011378aa76ac430f6b047fc5c14945060bdd11ed Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 2 Dec 2025 16:51:23 +0100 Subject: [PATCH 103/113] Update API of RoomLatestEventFormatter. --- .../RoomListRoomSummaryFactoryTest.kt | 5 ++- .../api/RoomLatestEventFormatter.kt | 5 ++- .../impl/DefaultRoomLatestEventFormatter.kt | 40 ++++++++++--------- .../DefaultRoomLatestEventFormatterTest.kt | 2 +- .../test/FakeRoomLatestEventFormatter.kt | 6 ++- 5 files changed, 33 insertions(+), 25 deletions(-) diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactoryTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactoryTest.kt index 941f889f69..5f307918be 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactoryTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactoryTest.kt @@ -11,11 +11,12 @@ package io.element.android.features.home.impl.datasource import io.element.android.libraries.dateformatter.api.DateFormatter import io.element.android.libraries.dateformatter.test.FakeDateFormatter import io.element.android.libraries.eventformatter.api.RoomLatestEventFormatter +import io.element.android.libraries.eventformatter.test.FakeRoomLatestEventFormatter fun aRoomListRoomSummaryFactory( dateFormatter: DateFormatter = FakeDateFormatter { _, _, _ -> "Today" }, - roomLatestEventFormatter: RoomLatestEventFormatter = RoomLatestEventFormatter { _, _ -> "Hey" } + roomLatestEventFormatter: RoomLatestEventFormatter = FakeRoomLatestEventFormatter(), ) = RoomListRoomSummaryFactory( dateFormatter = dateFormatter, - roomLatestEventFormatter = roomLatestEventFormatter + roomLatestEventFormatter = roomLatestEventFormatter, ) diff --git a/libraries/eventformatter/api/src/main/kotlin/io/element/android/libraries/eventformatter/api/RoomLatestEventFormatter.kt b/libraries/eventformatter/api/src/main/kotlin/io/element/android/libraries/eventformatter/api/RoomLatestEventFormatter.kt index 5eb7713b54..abb5cc929d 100644 --- a/libraries/eventformatter/api/src/main/kotlin/io/element/android/libraries/eventformatter/api/RoomLatestEventFormatter.kt +++ b/libraries/eventformatter/api/src/main/kotlin/io/element/android/libraries/eventformatter/api/RoomLatestEventFormatter.kt @@ -10,6 +10,7 @@ package io.element.android.libraries.eventformatter.api import io.element.android.libraries.matrix.api.roomlist.LatestEventValue -fun interface RoomLatestEventFormatter { - fun format(latestEvent: LatestEventValue, isDmRoom: Boolean): CharSequence? +interface RoomLatestEventFormatter { + fun format(latestEvent: LatestEventValue.Local, isDmRoom: Boolean): CharSequence? + fun format(latestEvent: LatestEventValue.Remote, isDmRoom: Boolean): CharSequence? } diff --git a/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatter.kt b/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatter.kt index 48b8c83bc6..7e1ffc3ee6 100644 --- a/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatter.kt +++ b/libraries/eventformatter/impl/src/main/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatter.kt @@ -59,25 +59,27 @@ class DefaultRoomLatestEventFormatter( private const val MAX_SAFE_LENGTH = 500 } - override fun format(latestEvent: LatestEventValue, isDmRoom: Boolean): CharSequence? { - return when (latestEvent) { - LatestEventValue.None -> null - is LatestEventValue.Local -> formatContent( - content = latestEvent.content, - isDmRoom = isDmRoom, - isOutgoing = true, - senderId = latestEvent.senderId, - senderDisambiguatedDisplayName = latestEvent.senderProfile.getDisambiguatedDisplayName(latestEvent.senderId) - ) - is LatestEventValue.Remote -> formatContent( - content = latestEvent.content, - isDmRoom = isDmRoom, - isOutgoing = latestEvent.isOwn, - senderId = latestEvent.senderId, - senderDisambiguatedDisplayName = latestEvent.senderProfile.getDisambiguatedDisplayName(latestEvent.senderId) - ) - } - } + override fun format( + latestEvent: LatestEventValue.Local, + isDmRoom: Boolean, + ): CharSequence? = formatContent( + content = latestEvent.content, + isDmRoom = isDmRoom, + isOutgoing = true, + senderId = latestEvent.senderId, + senderDisambiguatedDisplayName = latestEvent.senderProfile.getDisambiguatedDisplayName(latestEvent.senderId) + ) + + override fun format( + latestEvent: LatestEventValue.Remote, + isDmRoom: Boolean, + ): CharSequence? = formatContent( + content = latestEvent.content, + isDmRoom = isDmRoom, + isOutgoing = latestEvent.isOwn, + senderId = latestEvent.senderId, + senderDisambiguatedDisplayName = latestEvent.senderProfile.getDisambiguatedDisplayName(latestEvent.senderId) + ) private fun formatContent( content: EventContent, diff --git a/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatterTest.kt b/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatterTest.kt index 96d341f447..c06b79ead9 100644 --- a/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatterTest.kt +++ b/libraries/eventformatter/impl/src/test/kotlin/io/element/android/libraries/eventformatter/impl/DefaultRoomLatestEventFormatterTest.kt @@ -929,7 +929,7 @@ class DefaultRoomLatestEventFormatterTest { sentByYou: Boolean, senderDisplayName: String?, content: EventContent, - ): LatestEventValue { + ): LatestEventValue.Remote { val sender = if (sentByYou) A_USER_ID else someoneElseId val profile = aProfileDetails(senderDisplayName) return aRemoteLatestEvent( diff --git a/libraries/eventformatter/test/src/main/kotlin/io/element/android/libraries/eventformatter/test/FakeRoomLatestEventFormatter.kt b/libraries/eventformatter/test/src/main/kotlin/io/element/android/libraries/eventformatter/test/FakeRoomLatestEventFormatter.kt index d82128b2d3..5e1a056a6c 100644 --- a/libraries/eventformatter/test/src/main/kotlin/io/element/android/libraries/eventformatter/test/FakeRoomLatestEventFormatter.kt +++ b/libraries/eventformatter/test/src/main/kotlin/io/element/android/libraries/eventformatter/test/FakeRoomLatestEventFormatter.kt @@ -14,7 +14,11 @@ import io.element.android.libraries.matrix.api.roomlist.LatestEventValue class FakeRoomLatestEventFormatter : RoomLatestEventFormatter { private var result: CharSequence? = null - override fun format(latestEvent: LatestEventValue, isDmRoom: Boolean): CharSequence? { + override fun format(latestEvent: LatestEventValue.Local, isDmRoom: Boolean): CharSequence? { + return result + } + + override fun format(latestEvent: LatestEventValue.Remote, isDmRoom: Boolean): CharSequence? { return result } From 43de65a61201b2e149d8c3b41980da09c6892847 Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Tue, 2 Dec 2025 16:54:50 +0100 Subject: [PATCH 104/113] Rename LatestEvent.Regular to LatestEvent.Synced --- .../impl/datasource/RoomListRoomSummaryFactory.kt | 2 +- .../android/features/home/impl/model/LatestEvent.kt | 4 ++-- .../home/impl/model/RoomListRoomSummaryProvider.kt | 12 ++++++------ .../home/impl/roomlist/RoomListStateProvider.kt | 6 +++--- .../home/impl/model/RoomListBaseRoomSummaryTest.kt | 2 +- 5 files changed, 13 insertions(+), 13 deletions(-) diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt index 14121516d6..0200f495ef 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/datasource/RoomListRoomSummaryFactory.kt @@ -91,7 +91,7 @@ class RoomListRoomSummaryFactory( } is LatestEventValue.Remote -> { val content = roomLatestEventFormatter.format(latestEvent, dm).orEmpty() - LatestEvent.Regular( + LatestEvent.Synced( content = content, ) } diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/LatestEvent.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/LatestEvent.kt index 6a268e8284..d6ddcf258c 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/LatestEvent.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/LatestEvent.kt @@ -13,7 +13,7 @@ import androidx.compose.runtime.Immutable sealed interface LatestEvent { data object None : LatestEvent - data class Regular( + data class Synced( val content: CharSequence?, ) : LatestEvent @@ -26,7 +26,7 @@ sealed interface LatestEvent { fun content(): CharSequence? { return when (this) { is None -> null - is Regular -> content + is Synced -> content is Sending -> content is Error -> null } diff --git a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt index 65c70f98ed..400decff6f 100644 --- a/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt +++ b/features/home/impl/src/main/kotlin/io/element/android/features/home/impl/model/RoomListRoomSummaryProvider.kt @@ -28,7 +28,7 @@ open class RoomListRoomSummaryProvider : PreviewParameterProvider { name = "Room", numberOfUnreadMessages = 1, timestamp = "14:18", - latestEvent = LatestEvent.Regular("A very very very very long message which suites on two lines"), + latestEvent = LatestEvent.Synced("A very very very very long message which suites on two lines"), avatarData = AvatarData("!id", "R", size = AvatarSize.RoomListItem), id = "!roomId:domain", ), @@ -97,7 +97,7 @@ internal fun aRoomListRoomSummaryList(): ImmutableList { name = "Room#2", numberOfUnreadMessages = 0, timestamp = "14:16", - latestEvent = LatestEvent.Regular("A short message"), + latestEvent = LatestEvent.Synced("A short message"), avatarData = AvatarData("!id", "Z", size = AvatarSize.RoomListItem), id = "!roomId2:domain", ), @@ -120,7 +120,7 @@ internal fun generateRoomListRoomSummaryList( name = "Room#$index", numberOfUnreadMessages = 0, timestamp = "14:16", - latestEvent = LatestEvent.Regular("A message"), + latestEvent = LatestEvent.Synced("A message"), avatarData = AvatarData("!id$index", "${(65 + index % 26).toChar()}", size = AvatarSize.RoomListItem), id = "!roomId$index:domain", ) diff --git a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt index 0a5350d086..28e7051a55 100644 --- a/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt +++ b/features/home/impl/src/test/kotlin/io/element/android/features/home/impl/model/RoomListBaseRoomSummaryTest.kt @@ -96,7 +96,7 @@ internal fun createRoomListRoomSummary( numberOfUnreadNotifications = numberOfUnreadNotifications, isMarkedUnread = isMarkedUnread, timestamp = timestamp, - latestEvent = LatestEvent.Regular(""), + latestEvent = LatestEvent.Synced(""), avatarData = AvatarData(id = A_ROOM_ID.value, name = A_ROOM_NAME, size = AvatarSize.RoomListItem), displayType = displayType, userDefinedNotificationMode = userDefinedNotificationMode, From 6874d29532ee6eac304290df24ab89fd722cf5f9 Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 2 Dec 2025 17:03:56 +0100 Subject: [PATCH 105/113] fix(security&privacy): update string resources --- .../securityandprivacy/impl/root/SecurityAndPrivacyView.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index 32674ef34f..30e93ecb58 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -214,7 +214,7 @@ private fun RoomAccessSection( if (saved == SecurityAndPrivacyRoomAccess.SpaceMember) { ListItem( headlineContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_title)) }, - supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_description)) }, + supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_unavailable_description)) }, trailingContent = ListItemContent.RadioButton(selected = edited == SecurityAndPrivacyRoomAccess.SpaceMember, enabled = false), leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Workspace())), enabled = false, @@ -280,7 +280,7 @@ private fun RoomAddressSection( Text(text = roomAddress ?: stringResource(R.string.screen_security_and_privacy_add_room_address_action)) }, trailingContent = if (roomAddress.isNullOrEmpty()) ListItemContent.Icon(IconSource.Vector(CompoundIcons.Plus())) else null, - supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_address_description)) }, + supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_address_section_footer)) }, onClick = onRoomAddressClick, colors = ListItemDefaults.colors(trailingIconColor = ElementTheme.colors.iconAccentPrimary), ) From 78439c17aba0e7073864648eacae7ae8845977c2 Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Tue, 2 Dec 2025 16:42:05 +0100 Subject: [PATCH 106/113] Revert "fix(deps): update dependency com.posthog:posthog-android to v3.27.0" This reverts commit eedaeb6b3547a6811cd2bd3d2e48cc6fa56282c4. --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 95b431d67d..1a8ebd36a2 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -216,7 +216,7 @@ haze_materials = { module = "dev.chrisbanes.haze:haze-materials", version.ref = color_picker = "io.mhssn:colorpicker:1.0.0" # Analytics -posthog = "com.posthog:posthog-android:3.27.0" +posthog = "com.posthog:posthog-android:3.26.0" sentry = "io.sentry:sentry-android:8.27.1" # main branch can be tested replacing the version with main-SNAPSHOT matrix_analytics_events = "com.github.matrix-org:matrix-analytics-events:0.29.2" From c9bd8ec0bd04b4f02ac9e080611626c338fcd998 Mon Sep 17 00:00:00 2001 From: ElementBot Date: Tue, 2 Dec 2025 16:18:44 +0000 Subject: [PATCH 107/113] Update screenshots --- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en.png | 4 ++-- ...tyandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_10_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_11_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_12_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_13_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png | 4 ++-- ...andprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en.png | 4 ++-- ...yandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en.png | 4 ++-- 40 files changed, 80 insertions(+), 80 deletions(-) diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en.png index ae15fd2efd..a52b20decc 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:59cfdfa8b68af10024d8650b680481a37b5717d981999adce49a0e62d55e433f -size 38619 +oid sha256:71acb17375db16b8777221e3a09c85ce821920dfaf7853c456493371e4778b9d +size 37050 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en.png index 9ac055352b..5015b5c995 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b9c5983ff1143ef6c517dc948b9b60102607ff397748e8d87f3b565ab86efc4b -size 46360 +oid sha256:bef6e6c4cdd362577cf5dc91914a84c72465014a71a08f48c1f4a526be44c85c +size 39535 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en.png index d5640cc559..fbef6afae3 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64d0aecdae4cd8c7581ded462d8534620cd006a78a089a4333c1608e8023ead1 -size 46768 +oid sha256:39222fd299a2dec3cc60863878906eba5c9d86100a3e4bad781633a1a0372cc5 +size 39874 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en.png index 52e6f29adb..8abe7a325a 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:a4230969f15739f418eebe1d4a14e895c84bbe5bdbf832ccc60ae4bfafea0839 -size 19751 +oid sha256:5c9bf91f57bb68ae3341acecd62d418d1654a8d4cf271eeda9e87bc5e4998891 +size 20225 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en.png index 6f9172af47..3989ce8d6e 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4eb56b2db5b843d94f89c60baea02809d43733b718c59f0d06c1cee7ad4db9a7 -size 47036 +oid sha256:495fff852c9549125b3d3a681a880147f680d4604eee3cb13a8fc3dc47e7c729 +size 40476 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png index d5640cc559..fbef6afae3 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:64d0aecdae4cd8c7581ded462d8534620cd006a78a089a4333c1608e8023ead1 -size 46768 +oid sha256:39222fd299a2dec3cc60863878906eba5c9d86100a3e4bad781633a1a0372cc5 +size 39874 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png index f367faca6b..8bb18a4153 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b3f5880e027ca7f380d24144efe8de3a222e359f5bf2e700f5af701dbe5d9bec -size 47145 +oid sha256:cdd805d857d590437bde9be2a7df252ff42571d3b08be8085aae81dc75e896c3 +size 40235 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png index ef258a39e6..e8b0f4f2a3 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e6895ffbb2c5b10705135ca748d7bfb243c19c250d5f9a5fa3cedf3f83baba0c -size 33097 +oid sha256:b03d25813c75712a0b9e23622132bd63e07ca9ec593a1842dacf751347c06ea1 +size 32023 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png index c883064bb0..16b13d8a4f 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_17_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:2701337aad7fcdd419770718dc57c3ff6a1567cf23420624471a23120a3b9f8d -size 31593 +oid sha256:3aaf6da43b5f2882da986ae766d0057421b1f39f7f0bb467bd32f2a957608045 +size 31478 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png index d24af812f5..e8e5a2019d 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_18_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ced07a8e45e02c9fef27fa7bdbe969a26c73c850672d7b7167c58ff09cd9ed78 -size 32927 +oid sha256:4b1ce86ad21d9ccd5b170a1628985eadbc5ac92be521ab55e9a1b22eb48c1476 +size 32552 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png index a1c720f7c3..82cba49c78 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_19_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f91b888b3948956f57a3d4a94ebea36e5da6c39d606170e3bb748e9caca70127 -size 41892 +oid sha256:5343bc348bc1be7430243ce6fceeb7c81bbf2d5692486733221cb6c615d9aeea +size 41544 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en.png index 5b752d5035..53e3694e7b 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f4bda58361cf1c8dd39d634203038ab7c8ac130df1aa465fb9dfb37a439b1c72 -size 59877 +oid sha256:9cf6cd1f914a4f31608edceefde79632ebed0c8983d83d8a63c4408bcc2d4ff3 +size 56743 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en.png index 22f6338462..aa9712b151 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b3b390cabae48e7f5487737b89d2d9e7a18f538a4601a0b262fc205954ef70a3 -size 59439 +oid sha256:00a667f59cd097021a6d363d0e4f578cba6acc405aaaa74bddfa9a3286cfd26e +size 56408 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en.png index a28746d476..680b550efa 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:1ec795cb5ffcb06e29be3a59dd95d88232f518bae66f96c05f1b75197cefdbf3 -size 59992 +oid sha256:5bdcf84378968b8e37cc50a300ff19b1917354de764a9f81448e6ca3d4050386 +size 54711 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png index 2781d8a337..d2603fba50 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:d213f421daa486febb24033e0d3928b47e6380e21889636d6b51550ee66b99b8 -size 36843 +oid sha256:577eac69d32648070d896788474104fdf143c040e058f182d6b832e5ea83fad8 +size 37242 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png index 1a79cae3e1..cad3e46f71 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c604f0a5f6003f51da4dadff3a01080b54ff2f2e34a4a4a9d2fbf0e5fac20221 -size 60117 +oid sha256:745a270883c79932fdde14d11785d9e27d1ec0eee03999af5e494b5c6e30c309 +size 57329 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png index 2393e0a15b..f918b5ff28 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:67e064c056d4559c3ab183015f47aed82360c0a9846170ec95f83089c22c22a2 -size 59864 +oid sha256:451eee79c5ca4b61902044c58f99069065fcd11a9fa7d469d2568cd20ea134a3 +size 56743 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png index 2dd0307a7a..7f77181ea9 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:ea71f66e3a2e1b3e513c806875d59088a33a4dedcd198b409ef3ec1c6bab59ed -size 60223 +oid sha256:023b2870f5a4291ad8b521dc177db22972a47e5e965458c81cb8688da0cbe6b8 +size 57097 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en.png index 1e97e4c8f2..46ad8a30d5 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:db47cd993b12896c3439c7f4c9bddde833c5048a33f84b41aa15c48277cd53e9 -size 21577 +oid sha256:67bd76421dcb3e8a6c2c0a6aeda024dacb392b2f6d8bea278d6ffae7de5b4e8f +size 20023 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en.png index 169f1ad8f9..6b5c72706b 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewDark_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:83a1ff18c075d93b625ab55d2c54a767612b2af278ec6e5d1ebd9a509647c809 -size 46782 +oid sha256:48f50c8053f0f15228899e8bce1656a90cfaf936e6bc8ca725c676aff5578575 +size 39874 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en.png index 41d20622ba..80b8aeb70e 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_0_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:49bf2a919952035933e6d658076a845845f51fd33c2a3c21cc1f1e332ee95825 -size 40258 +oid sha256:1463d9c6b2d968c0a5f375e5135b31e31b32f2d35525e0be1c264d90ff4e723c +size 38652 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en.png index ecced7e27f..da192161cb 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_10_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:808934308408e850551bc3103cee5a37d85d106adf567105003b0144651ca408 -size 47683 +oid sha256:342cc313605f43325a0720fe9c9fa969ed7edd41258ce0768dc624fc4e74d66d +size 40636 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en.png index e2a98e5f81..4ddc1b913d 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_11_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bbf2bff6460019434e1af725763ef775240b832b947d7faea760ae08b31a1815 -size 48101 +oid sha256:adfd4213ac36d904a8a31b1c3bf5463ba72ad4760d084a4c412370d6d51cf250 +size 40996 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en.png index 59c10f26e9..32138581f7 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_12_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:7064846fe9af8d99fc1bf40ce410149a9b52cffab7b7d54b4383aace6689933e -size 20358 +oid sha256:4ef8e92812f6b65fc09ea4e77d44f9c32a74daebe8e2ef2a9e499588e46a43db +size 20823 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en.png index ae17ccb1aa..d274eddbe1 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_13_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:805fdb8f857bdffe88caccd4f62bc1c2251a8119a51e865e3b7da9b9f6ff22b0 -size 48377 +oid sha256:5547eb8b7f7ca596edf65bfd7703d1cb91fbf2e254374b9ea41d5c8754030e34 +size 41628 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png index e2a98e5f81..4ddc1b913d 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_14_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:bbf2bff6460019434e1af725763ef775240b832b947d7faea760ae08b31a1815 -size 48101 +oid sha256:adfd4213ac36d904a8a31b1c3bf5463ba72ad4760d084a4c412370d6d51cf250 +size 40996 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png index a17602cc6d..e939df2248 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_15_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:c121a184f66582bedf67ed73ec4740b3ce6984a264cfe04c241138bfa5d022a7 -size 48562 +oid sha256:40c6334e01cc858f343f9046cfbb5079b79369002f5194965b6c2e75dd37b134 +size 41437 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png index c7b5337e1b..7458fc24fa 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_16_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:11edb6109de15b857f90da338a0be8b5f1e202129fc3357ed3669ffc1edbf51a -size 34662 +oid sha256:09a88867a2f10ce346df8d683d614970f9aad8e8ec7bf06bddf27352dc0e5476 +size 33520 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png index a32249c2ad..eeac763a63 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_17_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:f55c84fb18a3a60b1621125edc305c6245f1bd042724198bf505ca1b7c39231c -size 33593 +oid sha256:81162b1f086e45797db0678eff6bc41ad35eb09a7ac436d540fd3b7e1feffbc6 +size 33534 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png index 1129971ac4..6625789361 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_18_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:4d11da663b4512e76a74774da0b191dc4a72daa0edfcf68ab011469c73302ff0 -size 35017 +oid sha256:da39e0496083394c522d40ed4cc62edc614ddca54ccfb05d5b7c68cfb030960a +size 34559 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png index d68df083c4..af2072ede6 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_19_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:398a2bb2ea12547edcc0af04fe85c83c4ea19aeb4e385d6e5b81b6a2eef96006 -size 44007 +oid sha256:b0ce43031e71ffadc53388a66a9ceb66b1c9bb33014a912161ec6006a303050b +size 43544 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en.png index 9af2e30e19..c9a99e421a 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_1_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:618d2b08a9eaf0a7e56403125c785937e7078bff435bcc76ecafd068921d8f2a -size 61912 +oid sha256:a906ec0c412892a241eab241836d4238c1883ec1d27f27b8a012de75894fdaf7 +size 58785 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en.png index 11df3bd052..4a47f17a41 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_2_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:b3d9c431a14e527cad513fc92a5081b0b4dc6ae5153d381456684eb06b88e1fe -size 61491 +oid sha256:8e4ccb39f3024e3a98be3bc0f94ce769e412b891ed988dad4cf1457aab3cea72 +size 58442 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en.png index 6e23df8b30..5176122680 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_3_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:84aff9af3ac8512db3790f8c41cde10b0fcfdf29b7390ea48f460e4e21a3cbe4 -size 62146 +oid sha256:e8b10af4e5006f45e2fe738a3a8a589551378ee9106c09f10b9de81fdbf12e61 +size 56716 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png index 8c60403815..db1c3dd777 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_4_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:67467daa13b1a5d404686ddf94ea9a133f3546b43770b6d1e264782ae054f198 -size 38350 +oid sha256:bc82d2ab3bc9d73726bcc0cdc5dc27b628d00db330cfcc7a78f177af029a7803 +size 38810 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png index 40ccd4d4fe..766e81c18a 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_5_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:0312b48791d6c0af66d25b01bc9f9f8f78dbf1808aafbf5251df3c6490e62e3a -size 62171 +oid sha256:aef64f63cb176feea3ee1e48de98f7bf6ed104370f84e377c963a2f26ba0fa49 +size 59387 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png index b9a696d0d2..55d3916eb4 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_6_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e9b1fa55fd171af2eef1bd6cb874b0e542dd32332f56e21c430f3f7767d56d35 -size 61905 +oid sha256:e6f46d940ee39961ea128fc7fc607dd6156d827121def3516ef62ff5f617e249 +size 58785 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png index 69b7b4374b..2c37ae11f9 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_7_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:958b45102cb3fcefd7461f86e1870ac44daf6c9f9b13583ba4f60106c20b6bab -size 62349 +oid sha256:6ea58c892886c9de971fd22a5a72340775cb0f973cdfb697d7f517100ce8b65d +size 59205 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en.png index 7a45fa88bb..83f51a3be7 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_8_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e37f1f6e15cee552219e997aa8dd491e672d73e55900f3e2cbdeea08f1355373 -size 22125 +oid sha256:8303e863849a00c16f00850854e8d4d7ceaf3fb097c7b20fe349127d8ed3b082 +size 20651 diff --git a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en.png b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en.png index 63616838a9..eea66871f9 100644 --- a/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en.png +++ b/tests/uitests/src/test/snapshots/images/features.securityandprivacy.impl.root_SecurityAndPrivacyViewLight_9_en.png @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:aeff0b99f3ca35b84735ad464c78f4b69ca6ba22bdc67eb4ef56268d04bbb859 -size 48109 +oid sha256:1626bffb649c204b0dcb1c92e7344d1b7f119b61ecac3c49840385f3a9a39515 +size 40998 From 213e7ed850dae67588893ac4516533b97c67e48e Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Tue, 2 Dec 2025 16:12:55 +0000 Subject: [PATCH 108/113] fix(deps): update dependency io.element.android:element-call-embedded to v0.16.3 --- gradle/libs.versions.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1a8ebd36a2..9e63c39535 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -229,7 +229,7 @@ sigpwned_emoji4j = "com.sigpwned:emoji4j-core:16.0.0" metro_runtime = { module = "dev.zacsweers.metro:runtime", version.ref = "metro" } # Element Call -element_call_embedded = "io.element.android:element-call-embedded:0.16.1" +element_call_embedded = "io.element.android:element-call-embedded:0.16.3" # Auto services google_autoservice = { module = "com.google.auto.service:auto-service", version.ref = "autoservice" } From 9756d0a5cbeab409316c70054999ffd93dace6ed Mon Sep 17 00:00:00 2001 From: Jorge Martin Espinosa Date: Tue, 2 Dec 2025 18:12:56 +0100 Subject: [PATCH 109/113] Upgrade the Rust SDK to `v25.12.2` (#5838) * Upgrade the Rust SDK to `v25.12.2` --- gradle/libs.versions.toml | 2 +- .../android/libraries/matrix/impl/room/JoinedRustRoom.kt | 3 ++- .../android/libraries/matrix/impl/room/RustRoomFactory.kt | 3 ++- .../matrix/impl/fixtures/factories/NotificationItem.kt | 2 ++ 4 files changed, 7 insertions(+), 3 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 9e63c39535..b910cb9b96 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -177,7 +177,7 @@ test_detekt_test = { module = "io.gitlab.arturbosch.detekt:detekt-test", version # https://github.com/matrix-org/matrix-rust-components-kotlin/commits/main/sdk/sdk-android/src/main/kotlin/org/matrix/rustcomponents/sdk/matrix_sdk_ffi.kt # All new features should not be implemented in the pull request that upgrades the version, developers should # only fix API breaks and may add some TODOs. -matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.11.26" +matrix_sdk = "org.matrix.rustcomponents:sdk-android:25.12.2" # Others coil = { module = "io.coil-kt.coil3:coil", version.ref = "coil" } diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/JoinedRustRoom.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/JoinedRustRoom.kt index 0af29e75b2..943b5ee1d5 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/JoinedRustRoom.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/JoinedRustRoom.kt @@ -77,6 +77,7 @@ import org.matrix.rustcomponents.sdk.getElementCallRequiredPermissions import org.matrix.rustcomponents.sdk.use import timber.log.Timber import uniffi.matrix_sdk.RoomPowerLevelChanges +import uniffi.matrix_sdk_ui.TimelineReadReceiptTracking import kotlin.coroutines.cancellation.CancellationException import org.matrix.rustcomponents.sdk.IdentityStatusChange as RustIdentityStateChange import org.matrix.rustcomponents.sdk.KnockRequest as InnerKnockRequest @@ -237,7 +238,7 @@ class JoinedRustRoom( filter = filter, internalIdPrefix = internalIdPrefix, dateDividerMode = dateDividerMode, - trackReadReceipts = trackReadReceipts, + trackReadReceipts = if (trackReadReceipts) TimelineReadReceiptTracking.ALL_EVENTS else TimelineReadReceiptTracking.DISABLED, reportUtds = true, ) ).let { innerTimeline -> diff --git a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt index 55498c150d..f184356f15 100644 --- a/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt +++ b/libraries/matrix/impl/src/main/kotlin/io/element/android/libraries/matrix/impl/room/RustRoomFactory.kt @@ -41,6 +41,7 @@ import org.matrix.rustcomponents.sdk.TimelineConfiguration import org.matrix.rustcomponents.sdk.TimelineFilter import org.matrix.rustcomponents.sdk.TimelineFocus import timber.log.Timber +import uniffi.matrix_sdk_ui.TimelineReadReceiptTracking import java.util.concurrent.atomic.AtomicBoolean import org.matrix.rustcomponents.sdk.RoomListService as InnerRoomListService @@ -133,7 +134,7 @@ class RustRoomFactory( filter = eventFilters?.let(TimelineFilter::EventTypeFilter) ?: TimelineFilter.All, internalIdPrefix = "live", dateDividerMode = DateDividerMode.DAILY, - trackReadReceipts = true, + trackReadReceipts = TimelineReadReceiptTracking.ALL_EVENTS, reportUtds = true, ) ) diff --git a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/NotificationItem.kt b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/NotificationItem.kt index 639dd7b6ec..e5b77b249c 100644 --- a/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/NotificationItem.kt +++ b/libraries/matrix/impl/src/test/kotlin/io/element/android/libraries/matrix/impl/fixtures/factories/NotificationItem.kt @@ -64,6 +64,7 @@ fun aRustNotificationRoomInfo( isEncrypted: Boolean? = true, isDirect: Boolean = false, joinRule: JoinRule? = null, + isSpace: Boolean = false, ) = NotificationRoomInfo( displayName = displayName, avatarUrl = avatarUrl, @@ -73,6 +74,7 @@ fun aRustNotificationRoomInfo( isEncrypted = isEncrypted, isDirect = isDirect, joinRule = joinRule, + isSpace = isSpace, ) fun aRustNotificationEventTimeline( From aaed75a3caa61b4ae5ccc722ed6ea680af11ef9e Mon Sep 17 00:00:00 2001 From: ganfra Date: Tue, 2 Dec 2025 20:26:42 +0100 Subject: [PATCH 110/113] quality: fix ktlint --- .../securityandprivacy/impl/root/SecurityAndPrivacyView.kt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt index 30e93ecb58..ad75580031 100644 --- a/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt +++ b/features/securityandprivacy/impl/src/main/kotlin/io/element/android/features/securityandprivacy/impl/root/SecurityAndPrivacyView.kt @@ -52,6 +52,7 @@ import io.element.android.libraries.designsystem.theme.components.TextButton import io.element.android.libraries.designsystem.theme.components.TopAppBar import io.element.android.libraries.ui.strings.CommonStrings import kotlinx.collections.immutable.ImmutableSet + @Composable fun SecurityAndPrivacyView( state: SecurityAndPrivacyState, @@ -214,7 +215,9 @@ private fun RoomAccessSection( if (saved == SecurityAndPrivacyRoomAccess.SpaceMember) { ListItem( headlineContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_title)) }, - supportingContent = { Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_unavailable_description)) }, + supportingContent = { + Text(text = stringResource(R.string.screen_security_and_privacy_room_access_space_members_option_unavailable_description)) + }, trailingContent = ListItemContent.RadioButton(selected = edited == SecurityAndPrivacyRoomAccess.SpaceMember, enabled = false), leadingContent = ListItemContent.Icon(IconSource.Vector(CompoundIcons.Workspace())), enabled = false, From fc27accb94a320f8db2463bd9103d82ec4d8c20a Mon Sep 17 00:00:00 2001 From: Benoit Marty Date: Wed, 3 Dec 2025 09:52:10 +0100 Subject: [PATCH 111/113] Remove useless `derivedStateOf` --- .../components/LiveWaveformView.kt | 21 +++++++------------ 1 file changed, 8 insertions(+), 13 deletions(-) diff --git a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/LiveWaveformView.kt b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/LiveWaveformView.kt index 5e4ad02bd6..d18b85c987 100644 --- a/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/LiveWaveformView.kt +++ b/libraries/textcomposer/impl/src/main/kotlin/io/element/android/libraries/textcomposer/components/LiveWaveformView.kt @@ -15,7 +15,6 @@ import androidx.compose.foundation.layout.fillMaxWidth import androidx.compose.foundation.layout.height import androidx.compose.foundation.layout.width import androidx.compose.runtime.Composable -import androidx.compose.runtime.derivedStateOf import androidx.compose.runtime.getValue import androidx.compose.runtime.mutableIntStateOf import androidx.compose.runtime.mutableStateOf @@ -51,27 +50,23 @@ fun LiveWaveformView( linePadding: Dp = 2.dp, ) { var canvasSize by remember { mutableStateOf(DpSize(0.dp, 0.dp)) } - var parentWidth by remember { mutableIntStateOf(0) } - - val waveformWidth by remember(levels.size, lineWidth, linePadding) { - derivedStateOf { - levels.size * (lineWidth.value + linePadding.value) - } + val waveformWidth = remember(levels.size, lineWidth, linePadding) { + levels.size * (lineWidth.value + linePadding.value) } Box( contentAlignment = Alignment.CenterEnd, modifier = modifier - .fillMaxWidth() - .height(waveFormHeight) - .onSizeChanged { parentWidth = it.width } + .fillMaxWidth() + .height(waveFormHeight) + .onSizeChanged { parentWidth = it.width } ) { Canvas( modifier = Modifier - .width(Dp(waveformWidth)) - .graphicsLayer(alpha = DEFAULT_GRAPHICS_LAYER_ALPHA) - .then(modifier) + .width(Dp(waveformWidth)) + .graphicsLayer(alpha = DEFAULT_GRAPHICS_LAYER_ALPHA) + .then(modifier) ) { val width = min(waveformWidth, parentWidth.toFloat()) canvasSize = DpSize(width.dp, size.height.toDp()) From dc442778f8f0de3145eda585343cc4e0c9214df7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 3 Dec 2025 10:31:20 +0100 Subject: [PATCH 112/113] Setting version for the release 25.12.0 --- plugins/src/main/kotlin/Versions.kt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/plugins/src/main/kotlin/Versions.kt b/plugins/src/main/kotlin/Versions.kt index 863b3ec79f..f00099753c 100644 --- a/plugins/src/main/kotlin/Versions.kt +++ b/plugins/src/main/kotlin/Versions.kt @@ -39,13 +39,13 @@ private const val versionYear = 25 * Month of the version on 2 digits. Value must be in [1,12]. * Do not update this value. it is updated by the release script. */ -private const val versionMonth = 11 +private const val versionMonth = 12 /** * Release number in the month. Value must be in [0,99]. * Do not update this value. it is updated by the release script. */ -private const val versionReleaseNumber = 3 +private const val versionReleaseNumber = 0 object Versions { /** From 8578f83caa870633103b5502e1327558e70e0e84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jorge=20Mart=C3=ADn?= Date: Wed, 3 Dec 2025 10:35:48 +0100 Subject: [PATCH 113/113] Adding fastlane file for version 25.12.0 --- fastlane/metadata/android/en-US/changelogs/202512000.txt | 6 ++++++ 1 file changed, 6 insertions(+) create mode 100644 fastlane/metadata/android/en-US/changelogs/202512000.txt diff --git a/fastlane/metadata/android/en-US/changelogs/202512000.txt b/fastlane/metadata/android/en-US/changelogs/202512000.txt new file mode 100644 index 0000000000..e287435043 --- /dev/null +++ b/fastlane/metadata/android/en-US/changelogs/202512000.txt @@ -0,0 +1,6 @@ +Main changes in this version: +- Improve the room security and privacy screens. +- Better room list sorting. +- Fixed crashes when recording long voice messages. +- Improved the UX when opening a room from the room list. +Full changelog: https://github.com/element-hq/element-x-android/releases \ No newline at end of file