From 1a333aabba759fb68449ead9c47e986f456e8c8c Mon Sep 17 00:00:00 2001
From: Sean King
+ {{ $t('post_status.edit_remote_warning') }}
+
+ {{ $t('post_status.edit_unsupported_warning') }}
+
- {{ edit ? localDescription : attachment.description }} + {{ localDescription }}
@@ -244,7 +244,7 @@- {{ attachment.description }} + {{ localDescription }}
M4a&z=*^F>86jhOfwZQ3&gn|xs2ru$$}9+VHFcuK&u~Et3XQ> zkrSG`-3P1{)H4oYNF91qV{;2+pzf0y`dUkrmn$G8+9i{;&8ZQSU9(G7C)3oT8x-^s z$obkTx9AOx_XfyOdP%KvlNvPtW!HgRtOJf`smv7Ct*!z20L{=Eb$S4!o621P5<$o7 zS$RcW+MsK*nT#`;C`H`Ml>}UOxeu_7ZB(#vN5d2seD+(oEeku!I(4v?N-EjP9ye{R zi(O`;mHJeJy>NB6(B>*T)id9i?VA?JJ{D2sB9NbO68*i3YXz9e>CEPP3?WR=xY&m| z$Ud66fUmsqM~3Qd#}lhkdXWn}3kTib$Q*~?SYC<zjs~xQyj4|p904FqJ}ffKTumN^OplL!biBb3X8=)~lcl%iFgyBhI0phB(U=n;i;rh6 z0L=z8d=PjwH;bVG{zw6^h3lh>2iC{trMPduyVaAqiN^m{lC(#~8mV@h21=*y)#j*4 zvO-Ttsx}$Ow)$X^mP?X0YmDeXE3>w_zS2_l)3uWB@;n-UfYEm`j`eJa?Cs&jIlS(G z4IZM71 e)x*^R!Kp)RcAT^d_?_B-uBep;k#@ovbgS|6HwF^tD >M_7lt0!Gm#AG2E1*I8nRZGF>k)O>VzBo$$OmhPE74i1 z=;rk 4fOGSKL9B*(8uh09{@42_)|9A2SD 118E$%4y&(hby!l433FkdhD~uUJp7>AQ Ia1g(7-Ek_ebYVV4aQj zXZVG+NJv;(Y%7NNW52K#DpFe ?Xz$c7}xqp{2jIz;wvMn|0+K50W z3+aqA21nUy|3iPU7SO&q&VbC%IC1s{GQcN5`X?GIcH&~^aDX-3!gN~^Gne+4&q}%J z)ecqZCXKu{M;r6IuYevkw5Op%uj#zzoB=^cXs5v~8h_1{A>m$Klse~Y9x?PIb}{c$ zuZ6vbviB~M>BNz&JZ5>CAfRik^(z $&kqJmX8(p+o z&C$Oz0r`c`MZBB#ADXd}11aS;`U1Te?+zyddBQ>ZtCy9+A4@+sEM>Zb&I8_!M_WZY zpS_4`mkm8r{(5QeCDZs3xvo#ZfIAXbeq%?ZKOb>yAAqr)8HxF*u_JP4pMcTC!enW+ zheo7;y?sENw{vdt0t>+yBeB@`FgjR}s!qfqAk&QoBHYj@EtE%|PwfHzpC%f8sd Liea%!mIGIh>to}TsFAf{+?GeiOBvWv~9cC~mZ=ds1R@-@D#FsL%f>J9m z+$ex=jy_}2!3`nXEKuV+An&jtlm#zW`3}h7)~tkblkb3NppA#4GSc~e!S2}Twguf? z#TLG#3;2vSW-*<~Jwo1PME2}?sxfI0OD!i;RO%9i+Il5XbfBR+M-OPPkz6flx1FLq zu{XojV5!veZ!%O94``VYAT{cjT>^8xg$kBUoW-v*=o}f!LK$HvzbIY Z=^hBdQ!E;?`9e!9gIjp3~Lo ?`f~+Kl4LG4vx*NXq@Mdy&T#KA!w`@f8%&y3Xy v6 y&S4O5XG}v6cqJnNovx-N+<%7# z3eD?v3Q4`X)TAy|>reWDj&)L#*))*xy-G_*RHeUYst}r_+JuAZx?xUq{$|tB_)v84 z>v@J(c!MvZe|v}#y~PQLaJP|t4aR4!ha?@;4GH@O%ahJjAL~?~9@*T1CMP+as=sz8 zfN0k;Q-!46+!-2wEloIJXq`^m=j%hXlU*nFIz@4(uF!BN=TYVcNM7_*h3+Z$9*s49 zJg_%F&WM4rPScd%H_m5IyhdriB P) 2EIDMKk8bhK5cDl*eDwKJ6u zbu=Q@s@18Cm~Gw4D|^T7|Y2M5(1^sDMzg11Thgq`B<={g5?ecN4nrp7ZWG?eM%G zvhSOm=gn`=bIy6rb8Zpw-jFDlK`w*5Ye1?QRd|p{2!;J2YPjXS0CI}q%;44D`w@JW z{roy)64}14S5neOAv(} =*XQ0KAWx#Q09? z*&z0_nUXLqD`s6|ck1U-=Ch*rX$fCsC~J}TAT7jexsH0SN z^MHCHX~r9&sP}UXcd>&qKgvik zck>{T04dG^CEUn577zt0X?I^nqIz6O1(Af7=}sN*y>C_2eS;X$*A-OG>q6T7PUnSv zFWk%50w)_xd0G|lJNHiGVs=t&`0fOgIOew2D&Zkx40y8nnCt5I3mL6;eznZTO2;jG zwceJgB(?5Iw{CnBdc+u`OV_Wr?4krO>|;1$!PQ*Nk6pVcjaEG7+o-e)5;O~^Dj^$^ zRHIw(_eM*7$_Q(yb!S>JK4tCAWo&c@auZW6zI!d7w&%tNskNdUpuutxP0+$|F7R ufg3`t+ep$%sca`kR+xo4h7q(@e%uCjr zFgVmbC04LntBldC;F%Q08LJ?5v8uuaA7;|X6ym^9cJK^OSVbAfxk7=w@cNtyM1TY_ zxYe?8oiAWGXj0!looLa?iy)euwCoSVf_@{2`GLTzG&=!VH;HQixDY5PH}ISP=*HKI z@Lh_57x{ee;6d(r^M|x=zbDl;H~o=sNRp1IMkCY_xO4lUcK7y09@S4J9aE(6efD8` zSdz3`V?-y~o_A}0S{qcNJ0)!@c%S`EMr~po&+@0_(UdJNd;n2RIbnHprnMpug*XQ_D_|2FkxUj`k40g*m^e_ruBWy zELZuaXEPs~(dvw0oZO^Um0rz!h`*n$sbQR8Qo$;B!wT6ll%G(VXWH8f9S#~;%6Woo z4bs=}rXM+SpAiOp(hJktda;+1ugvqqv_^5 2T$DC>pK#HuG=ZyD8VTa|8K@#NU zyl2a`hW2g2MVZTT&ao+PH@-(Yspu2GEO4K_@6~8L5I4?`x$)0hXx}~PA;L?>gEm!u zfc%F8h8i0D0D+x`>1X-^@+-skrOp?SLmW=K-@|VLrLXk`1fEN~o6r5c5+L=&E^k1d z%D7+2O4@QxJ*0TB4-FzhRT)EaC%S_*lnuTt7CXn&Y4=wa)v+r;`bEB&7FiRP)&+_o z-sX#Gp XpKpOAEw2lP5dbBK|L{^51`- ehMvF4W zx?h<8|L^B3eRh2a8t{uS+!xb=xAGqIXrVRu;8B ;;N}EQ8wqI> zhFV@GZcxG!OyGnMIdTm}v>2q1r6%S&2YHNm-nAAafTg~akrIPARX5@Tot}VPWf03P zCBgWTL4JUA7^IC5BNi-2!vi_QR$egDFv<@QSkHY%>8JPtLeMHSqb(Wh56A?gax&f@ zkb1*-j3*!w!-Y)MzJOd!g;DwnUqHr~b_2RR0hwi({>tJqKR_lJrjIh(50Kf$mBn=) zfFw;Pq$Pn*xbGoClvd-75Ly}H-n51@$XG{N?q5ZCAX6<&5iH8x-wF?8mK7}(?m=c) z(GqhEk~D8cdL-vD;qYp$CWcxGVRX4Qttf*nXnBJ!*JWg!l}&LEx^LNsSkbcAJxHAu zEeG6##I0yK;vOVoMa#e3gV>n(p9nGmH!P4T7Id5lGBO+%h>b%Dx`P;KSRntkpraYN z2dT4CMsN?(WkJVTA3(-i(9z}`Byn*IsDiacp@2j&43?&PhwZLGBBfUJs?2#AsVV$I z&2T{M^w%rhH;8un>s3M4$%g|n&5D+xLAuM~fQ+ I_z zb7a27L%yP^bIP26EHh|9y87|AoPjJhXvw4bdu_HsCK^qo$^LIjU4fXni`i~_xf775 zV6D-l%uG4U%K=K5#j93Ly~`&rXm7ydy3*yG8Z|WcciTM=v6>x>rI};=h3DDUkEyit z215q)YDEO-;xQiK#ei#qLR!%i*XB#+N21?-{gX=Q=bG%tnW40yxE{#EtUA@H4 ER&$$oP;cn>Xu*@LYPmIIRIn{AEGquSYk@21kjh9z zAJX}Ltp8q>2`y81+VivO)_Ha7n7*gQ8gH^Evu%)x8Cy#y^}2qjnL?;uO&Ne~Da eHm$^GwWP)@4fEs|Pvch=6z%loaVUenc{9@*T9 zrl}(9d8rO(L3C)dt&OA=T7#H*ZOB^0x=Ztpdwqy@{|BqJr(qn_YE|1i__R Date: Tue, 23 Aug 2022 02:06:54 +0300 Subject: [PATCH 28/80] fetch text height only after mask has been loaded --- .../update_notification/update_notification.js | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/src/components/update_notification/update_notification.js b/src/components/update_notification/update_notification.js index 6cfe893c8..c389750d8 100644 --- a/src/components/update_notification/update_notification.js +++ b/src/components/update_notification/update_notification.js @@ -60,9 +60,14 @@ const UpdateNotification = { } }, mounted () { - setTimeout(() => { - this.contentHeight = this.$refs.animatedText.scrollHeight - }, 1000) + // Workaround to get the text height only after mask loaded. A bit hacky. + const newImg = new Image() + newImg.onload = () => { + setTimeout(() => { + this.contentHeight = this.$refs.animatedText.scrollHeight + }, 100) + } + newImg.src = this.pleromaTanVariant === pleromaTan ? pleromaTanMask : pleromaTanFoxMask } } From 09a0339e1df87f9cd4d5fef8cdd8a39139713c75 Mon Sep 17 00:00:00 2001 From: Pleroma Renovate Bot Date: Wed, 31 Aug 2022 09:09:36 +0000 Subject: [PATCH 29/80] Update vue monorepo to v3.2.38 --- package.json | 4 +- yarn.lock | 136 +++++++++++++++++++++++++-------------------------- 2 files changed, 70 insertions(+), 70 deletions(-) diff --git a/package.json b/package.json index a3a4d6b10..5160266f0 100644 --- a/package.json +++ b/package.json @@ -41,7 +41,7 @@ "querystring-es3": "0.2.1", "url": "0.11.0", "utf8": "3.0.0", - "vue": "3.2.37", + "vue": "3.2.38", "vue-i18n": "9.2.2", "vue-router": "4.1.5", "vue-template-compiler": "2.7.10", @@ -57,7 +57,7 @@ "@ungap/event-target": "0.2.3", "@vue/babel-helper-vue-jsx-merge-props": "1.4.0", "@vue/babel-plugin-jsx": "1.1.1", - "@vue/compiler-sfc": "3.2.37", + "@vue/compiler-sfc": "3.2.38", "@vue/test-utils": "2.0.2", "autoprefixer": "10.4.8", "babel-loader": "8.2.5", diff --git a/yarn.lock b/yarn.lock index 383f1d66e..0051a9f21 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1882,47 +1882,47 @@ html-tags "^3.1.0" svg-tags "^1.0.0" -"@vue/compiler-core@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.37.tgz#b3c42e04c0e0f2c496ff1784e543fbefe91e215a" - integrity sha512-81KhEjo7YAOh0vQJoSmAD68wLfYqJvoiD4ulyedzF+OEk/bk6/hx3fTNVfuzugIIaTrOx4PGx6pAiBRe5e9Zmg== +"@vue/compiler-core@3.2.38": + version "3.2.38" + resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.38.tgz#0a2a7bffd2280ac19a96baf5301838a2cf1964d7" + integrity sha512-/FsvnSu7Z+lkd/8KXMa4yYNUiqQrI22135gfsQYVGuh5tqEgOB0XqrUdb/KnCLa5+TmQLPwvyUnKMyCpu+SX3Q== dependencies: "@babel/parser" "^7.16.4" - "@vue/shared" "3.2.37" + "@vue/shared" "3.2.38" estree-walker "^2.0.2" source-map "^0.6.1" -"@vue/compiler-dom@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.37.tgz#10d2427a789e7c707c872da9d678c82a0c6582b5" - integrity sha512-yxJLH167fucHKxaqXpYk7x8z7mMEnXOw3G2q62FTkmsvNxu4FQSu5+3UMb+L7fjKa26DEzhrmCxAgFLLIzVfqQ== +"@vue/compiler-dom@3.2.38": + version "3.2.38" + resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.38.tgz#53d04ed0c0c62d1ef259bf82f9b28100a880b6fd" + integrity sha512-zqX4FgUbw56kzHlgYuEEJR8mefFiiyR3u96498+zWPsLeh1WKvgIReoNE+U7gG8bCUdvsrJ0JRmev0Ky6n2O0g== dependencies: - "@vue/compiler-core" "3.2.37" - "@vue/shared" "3.2.37" + "@vue/compiler-core" "3.2.38" + "@vue/shared" "3.2.38" -"@vue/compiler-sfc@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.37.tgz#3103af3da2f40286edcd85ea495dcb35bc7f5ff4" - integrity sha512-+7i/2+9LYlpqDv+KTtWhOZH+pa8/HnX/905MdVmAcI/mPQOBwkHHIzrsEsucyOIZQYMkXUiTkmZq5am/NyXKkg== +"@vue/compiler-sfc@3.2.38": + version "3.2.38" + resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.38.tgz#9e763019471a535eb1fceeaac9d4d18a83f0940f" + integrity sha512-KZjrW32KloMYtTcHAFuw3CqsyWc5X6seb8KbkANSWt3Cz9p2qA8c1GJpSkksFP9ABb6an0FLCFl46ZFXx3kKpg== dependencies: "@babel/parser" "^7.16.4" - "@vue/compiler-core" "3.2.37" - "@vue/compiler-dom" "3.2.37" - "@vue/compiler-ssr" "3.2.37" - "@vue/reactivity-transform" "3.2.37" - "@vue/shared" "3.2.37" + "@vue/compiler-core" "3.2.38" + "@vue/compiler-dom" "3.2.38" + "@vue/compiler-ssr" "3.2.38" + "@vue/reactivity-transform" "3.2.38" + "@vue/shared" "3.2.38" estree-walker "^2.0.2" magic-string "^0.25.7" postcss "^8.1.10" source-map "^0.6.1" -"@vue/compiler-ssr@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.37.tgz#4899d19f3a5fafd61524a9d1aee8eb0505313cff" - integrity sha512-7mQJD7HdXxQjktmsWp/J67lThEIcxLemz1Vb5I6rYJHR5vI+lON3nPGOH3ubmbvYGt8xEUaAr1j7/tIFWiEOqw== +"@vue/compiler-ssr@3.2.38": + version "3.2.38" + resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.38.tgz#933b23bf99e667e5078eefc6ba94cb95fd765dfe" + integrity sha512-bm9jOeyv1H3UskNm4S6IfueKjUNFmi2kRweFIGnqaGkkRePjwEcfCVqyS3roe7HvF4ugsEkhf4+kIvDhip6XzQ== dependencies: - "@vue/compiler-dom" "3.2.37" - "@vue/shared" "3.2.37" + "@vue/compiler-dom" "3.2.38" + "@vue/shared" "3.2.38" "@vue/devtools-api@^6.0.0-beta.11": version "6.1.3" @@ -1934,53 +1934,53 @@ resolved "https://registry.yarnpkg.com/@vue/devtools-api/-/devtools-api-6.2.1.tgz#6f2948ff002ec46df01420dfeff91de16c5b4092" integrity sha512-OEgAMeQXvCoJ+1x8WyQuVZzFo0wcyCmUR3baRVLmKBo1LmYZWMlRiXlux5jd0fqVJu6PfDbOrZItVqUEzLobeQ== -"@vue/reactivity-transform@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.2.37.tgz#0caa47c4344df4ae59f5a05dde2a8758829f8eca" - integrity sha512-IWopkKEb+8qpu/1eMKVeXrK0NLw9HicGviJzhJDEyfxTR9e1WtpnnbYkJWurX6WwoFP0sz10xQg8yL8lgskAZg== +"@vue/reactivity-transform@3.2.38": + version "3.2.38" + resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.2.38.tgz#a856c217b2ead99eefb6fddb1d61119b2cb67984" + integrity sha512-3SD3Jmi1yXrDwiNJqQ6fs1x61WsDLqVk4NyKVz78mkaIRh6d3IqtRnptgRfXn+Fzf+m6B1KxBYWq1APj6h4qeA== dependencies: "@babel/parser" "^7.16.4" - "@vue/compiler-core" "3.2.37" - "@vue/shared" "3.2.37" + "@vue/compiler-core" "3.2.38" + "@vue/shared" "3.2.38" estree-walker "^2.0.2" magic-string "^0.25.7" -"@vue/reactivity@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.37.tgz#5bc3847ac58828e2b78526e08219e0a1089f8848" - integrity sha512-/7WRafBOshOc6m3F7plwzPeCu/RCVv9uMpOwa/5PiY1Zz+WLVRWiy0MYKwmg19KBdGtFWsmZ4cD+LOdVPcs52A== +"@vue/reactivity@3.2.38": + version "3.2.38" + resolved "https://registry.yarnpkg.com/@vue/reactivity/-/reactivity-3.2.38.tgz#d576fdcea98eefb96a1f1ad456e289263e87292e" + integrity sha512-6L4myYcH9HG2M25co7/BSo0skKFHpAN8PhkNPM4xRVkyGl1K5M3Jx4rp5bsYhvYze2K4+l+pioN4e6ZwFLUVtw== dependencies: - "@vue/shared" "3.2.37" + "@vue/shared" "3.2.38" -"@vue/runtime-core@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.37.tgz#7ba7c54bb56e5d70edfc2f05766e1ca8519966e3" - integrity sha512-JPcd9kFyEdXLl/i0ClS7lwgcs0QpUAWj+SKX2ZC3ANKi1U4DOtiEr6cRqFXsPwY5u1L9fAjkinIdB8Rz3FoYNQ== +"@vue/runtime-core@3.2.38": + version "3.2.38" + resolved "https://registry.yarnpkg.com/@vue/runtime-core/-/runtime-core-3.2.38.tgz#d19cf591c210713f80e6a94ffbfef307c27aea06" + integrity sha512-kk0qiSiXUU/IKxZw31824rxmFzrLr3TL6ZcbrxWTKivadoKupdlzbQM4SlGo4MU6Zzrqv4fzyUasTU1jDoEnzg== dependencies: - "@vue/reactivity" "3.2.37" - "@vue/shared" "3.2.37" + "@vue/reactivity" "3.2.38" + "@vue/shared" "3.2.38" -"@vue/runtime-dom@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.37.tgz#002bdc8228fa63949317756fb1e92cdd3f9f4bbd" - integrity sha512-HimKdh9BepShW6YozwRKAYjYQWg9mQn63RGEiSswMbW+ssIht1MILYlVGkAGGQbkhSh31PCdoUcfiu4apXJoPw== +"@vue/runtime-dom@3.2.38": + version "3.2.38" + resolved "https://registry.yarnpkg.com/@vue/runtime-dom/-/runtime-dom-3.2.38.tgz#fec711f65c2485991289fd4798780aa506469b48" + integrity sha512-4PKAb/ck2TjxdMSzMsnHViOrrwpudk4/A56uZjhzvusoEU9xqa5dygksbzYepdZeB5NqtRw5fRhWIiQlRVK45A== dependencies: - "@vue/runtime-core" "3.2.37" - "@vue/shared" "3.2.37" + "@vue/runtime-core" "3.2.38" + "@vue/shared" "3.2.38" csstype "^2.6.8" -"@vue/server-renderer@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.37.tgz#840a29c8dcc29bddd9b5f5ffa22b95c0e72afdfc" - integrity sha512-kLITEJvaYgZQ2h47hIzPh2K3jG8c1zCVbp/o/bzQOyvzaKiCquKS7AaioPI28GNxIsE/zSx+EwWYsNxDCX95MA== +"@vue/server-renderer@3.2.38": + version "3.2.38" + resolved "https://registry.yarnpkg.com/@vue/server-renderer/-/server-renderer-3.2.38.tgz#01a4c0f218e90b8ad1815074208a1974ded109aa" + integrity sha512-pg+JanpbOZ5kEfOZzO2bt02YHd+ELhYP8zPeLU1H0e7lg079NtuuSB8fjLdn58c4Ou8UQ6C1/P+528nXnLPAhA== dependencies: - "@vue/compiler-ssr" "3.2.37" - "@vue/shared" "3.2.37" + "@vue/compiler-ssr" "3.2.38" + "@vue/shared" "3.2.38" -"@vue/shared@3.2.37": - version "3.2.37" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.37.tgz#8e6adc3f2759af52f0e85863dfb0b711ecc5c702" - integrity sha512-4rSJemR2NQIo9Klm1vabqWjD8rs/ZaJSzMxkMNeJS6lHiUjjUeYFbooN19NgFjztubEKh3WlZUeOLVdbbUWHsw== +"@vue/shared@3.2.38": + version "3.2.38" + resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.38.tgz#e823f0cb2e85b6bf43430c0d6811b1441c300f3c" + integrity sha512-dTyhTIRmGXBjxJE+skC8tTWCGLCVc4wQgRRLt8+O9p5ewBAjoBwtCAkLPrtToSr1xltoe3st21Pv953aOZ7alg== "@vue/test-utils@2.0.2": version "2.0.2" @@ -8340,16 +8340,16 @@ vue-template-compiler@2.7.10: de-indent "^1.0.2" he "^1.2.0" -vue@3.2.37: - version "3.2.37" - resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.37.tgz#da220ccb618d78579d25b06c7c21498ca4e5452e" - integrity sha512-bOKEZxrm8Eh+fveCqS1/NkG/n6aMidsI6hahas7pa0w/l7jkbssJVsRhVDs07IdDq7h9KHswZOgItnwJAgtVtQ== +vue@3.2.38: + version "3.2.38" + resolved "https://registry.yarnpkg.com/vue/-/vue-3.2.38.tgz#cda3a414631745b194971219318a792dbbccdec0" + integrity sha512-hHrScEFSmDAWL0cwO4B6WO7D3sALZPbfuThDsGBebthrNlDxdJZpGR3WB87VbjpPh96mep1+KzukYEhpHDFa8Q== dependencies: - "@vue/compiler-dom" "3.2.37" - "@vue/compiler-sfc" "3.2.37" - "@vue/runtime-dom" "3.2.37" - "@vue/server-renderer" "3.2.37" - "@vue/shared" "3.2.37" + "@vue/compiler-dom" "3.2.38" + "@vue/compiler-sfc" "3.2.38" + "@vue/runtime-dom" "3.2.38" + "@vue/server-renderer" "3.2.38" + "@vue/shared" "3.2.38" vuex@4.0.2: version "4.0.2" From 0d217fe96324ba5aeba5ba08fa9aa529a7f94370 Mon Sep 17 00:00:00 2001 From: Pleroma Renovate Bot Date: Thu, 1 Sep 2022 09:08:18 +0000 Subject: [PATCH 30/80] Update dependency sass to v1.54.8 --- package.json | 2 +- yarn.lock | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/package.json b/package.json index a3a4d6b10..54658b74a 100644 --- a/package.json +++ b/package.json @@ -104,7 +104,7 @@ "ora": "0.4.1", "postcss": "8.4.16", "postcss-loader": "7.0.1", - "sass": "1.54.5", + "sass": "1.54.8", "sass-loader": "13.0.2", "selenium-server": "2.53.1", "semver": "7.3.7", diff --git a/yarn.lock b/yarn.lock index 383f1d66e..8268f4511 100644 --- a/yarn.lock +++ b/yarn.lock @@ -7382,10 +7382,10 @@ sass-loader@13.0.2: klona "^2.0.4" neo-async "^2.6.2" -sass@1.54.5: - version "1.54.5" - resolved "https://registry.yarnpkg.com/sass/-/sass-1.54.5.tgz#93708f5560784f6ff2eab8542ade021a4a947b3a" - integrity sha512-p7DTOzxkUPa/63FU0R3KApkRHwcVZYC0PLnLm5iyZACyp15qSi32x7zVUhRdABAATmkALqgGrjCJAcWvobmhHw== +sass@1.54.8: + version "1.54.8" + resolved "https://registry.yarnpkg.com/sass/-/sass-1.54.8.tgz#4adef0dd86ea2b1e4074f551eeda4fc5f812a996" + integrity sha512-ib4JhLRRgbg6QVy6bsv5uJxnJMTS2soVcCp9Y88Extyy13A8vV0G1fAwujOzmNkFQbR3LvedudAMbtuNRPbQww== dependencies: chokidar ">=3.0.0 <4.0.0" immutable "^4.0.0" From 41295a3b979915f3e7fe7b916b65a59769284d69 Mon Sep 17 00:00:00 2001 From: Pleroma Renovate Bot Date: Mon, 5 Sep 2022 09:07:46 +0000 Subject: [PATCH 31/80] Update Font Awesome to v6.2.0 --- package.json | 6 +++--- yarn.lock | 38 +++++++++++++++++++------------------- 2 files changed, 22 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 92f4b6c45..50a6b55f8 100644 --- a/package.json +++ b/package.json @@ -18,9 +18,9 @@ "dependencies": { "@babel/runtime": "7.18.9", "@chenfengyuan/vue-qrcode": "2.0.0", - "@fortawesome/fontawesome-svg-core": "6.1.2", - "@fortawesome/free-regular-svg-icons": "6.1.2", - "@fortawesome/free-solid-svg-icons": "6.1.2", + "@fortawesome/fontawesome-svg-core": "6.2.0", + "@fortawesome/free-regular-svg-icons": "6.2.0", + "@fortawesome/free-solid-svg-icons": "6.2.0", "@fortawesome/vue-fontawesome": "3.0.1", "@kazvmoe-infra/pinch-zoom-element": "1.2.0", "@ruffle-rs/ruffle": "0.1.0-nightly.2022.7.12", diff --git a/yarn.lock b/yarn.lock index f7443edf9..2fefe76f2 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1433,31 +1433,31 @@ minimatch "^3.1.2" strip-json-comments "^3.1.1" -"@fortawesome/fontawesome-common-types@6.1.2": - version "6.1.2" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.1.2.tgz#c1095b1bbabf19f37f9ff0719db38d92a410bcfe" - integrity sha512-wBaAPGz1Awxg05e0PBRkDRuTsy4B3dpBm+zreTTyd9TH4uUM27cAL4xWyWR0rLJCrRwzVsQ4hF3FvM6rqydKPA== +"@fortawesome/fontawesome-common-types@6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-common-types/-/fontawesome-common-types-6.2.0.tgz#76467a94aa888aeb22aafa43eb6ff889df3a5a7f" + integrity sha512-rBevIsj2nclStJ7AxTdfsa3ovHb1H+qApwrxcTVo+NNdeJiB9V75hsKfrkG5AwNcRUNxrPPiScGYCNmLMoh8pg== -"@fortawesome/fontawesome-svg-core@6.1.2": - version "6.1.2" - resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.1.2.tgz#11e2e8583a7dea75d734e4d0e53d91c63fae7511" - integrity sha512-853G/Htp0BOdXnPoeCPTjFrVwyrJHpe8MhjB/DYE9XjwhnNDfuBCd3aKc2YUYbEfHEcBws4UAA0kA9dymZKGjA== +"@fortawesome/fontawesome-svg-core@6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@fortawesome/fontawesome-svg-core/-/fontawesome-svg-core-6.2.0.tgz#11856eaf4dd1d865c442ddea1eed8ee855186ba2" + integrity sha512-Cf2mAAeMWFMzpLC7Y9H1I4o3wEU+XovVJhTiNG8ZNgSQj53yl7OCJaS80K4YjrABWZzbAHVaoHE1dVJ27AAYXw== dependencies: - "@fortawesome/fontawesome-common-types" "6.1.2" + "@fortawesome/fontawesome-common-types" "6.2.0" -"@fortawesome/free-regular-svg-icons@6.1.2": - version "6.1.2" - resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.1.2.tgz#9f04009098addcc11d0d185126f058ed042c3099" - integrity sha512-xR4hA+tAwsaTHGfb+25H1gVU/aJ0Rzu+xIUfnyrhaL13yNQ7TWiI2RvzniAaB+VGHDU2a+Pk96Ve+pkN3/+TTQ== +"@fortawesome/free-regular-svg-icons@6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@fortawesome/free-regular-svg-icons/-/free-regular-svg-icons-6.2.0.tgz#947e1f03be17da3a60bfeb2666b5348b19448ce2" + integrity sha512-M1dG+PAmkYMTL9BSUHFXY5oaHwBYfHCPhbJ8qj8JELsc9XCrUJ6eEHWip4q0tE+h9C0DVyFkwIM9t7QYyCpprQ== dependencies: - "@fortawesome/fontawesome-common-types" "6.1.2" + "@fortawesome/fontawesome-common-types" "6.2.0" -"@fortawesome/free-solid-svg-icons@6.1.2": - version "6.1.2" - resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.1.2.tgz#491d668b8a6603698d0ce1ac620f66fd22b74c84" - integrity sha512-lTgZz+cMpzjkHmCwOG3E1ilUZrnINYdqMmrkv30EC3XbRsGlbIOL8H9LaNp5SV4g0pNJDfQ4EdTWWaMvdwyLiQ== +"@fortawesome/free-solid-svg-icons@6.2.0": + version "6.2.0" + resolved "https://registry.yarnpkg.com/@fortawesome/free-solid-svg-icons/-/free-solid-svg-icons-6.2.0.tgz#8dcde48109354fd7a5ece8ea48d678bb91d4b5f0" + integrity sha512-UjCILHIQ4I8cN46EiQn0CZL/h8AwCGgR//1c4R96Q5viSRwuKVo0NdQEc4bm+69ZwC0dUvjbDqAHF1RR5FA3XA== dependencies: - "@fortawesome/fontawesome-common-types" "6.1.2" + "@fortawesome/fontawesome-common-types" "6.2.0" "@fortawesome/vue-fontawesome@3.0.1": version "3.0.1" From 12b0561992e464e4301f7df0c8ce8840e5e6f642 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Wed, 7 Sep 2022 19:52:50 -0400 Subject: [PATCH 32/80] Fix follow request count --- src/modules/api.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/api.js b/src/modules/api.js index f783fa4fd..b714c9ee5 100644 --- a/src/modules/api.js +++ b/src/modules/api.js @@ -16,7 +16,7 @@ const api = { followRequests: [] }, getters: { - followRequestCount: state => state.api.followRequests.length + followRequestCount: state => state.followRequests.length }, mutations: { setBackendInteractor (state, backendInteractor) { From 12d8d1711bb41b14c35914cb82a6d5f41943e198 Mon Sep 17 00:00:00 2001 From: Sean King Date: Thu, 15 Sep 2022 22:02:58 -0600 Subject: [PATCH 33/80] Added support for removing users from followers --- src/components/account_actions/account_actions.js | 3 +++ src/components/account_actions/account_actions.vue | 7 +++++++ src/i18n/en.json | 1 + src/modules/users.js | 8 ++++++++ src/services/api/api.service.js | 9 +++++++++ 5 files changed, 28 insertions(+) diff --git a/src/components/account_actions/account_actions.js b/src/components/account_actions/account_actions.js index 735dd81c1..c23407f90 100644 --- a/src/components/account_actions/account_actions.js +++ b/src/components/account_actions/account_actions.js @@ -36,6 +36,9 @@ const AccountActions = { unblockUser () { this.$store.dispatch('unblockUser', this.user.id) }, + removeUserFromFollowers () { + this.$store.dispatch('removeUserFromFollowers', this.user.id) + }, reportUser () { this.$store.dispatch('openUserReportingModal', { userId: this.user.id }) }, diff --git a/src/components/account_actions/account_actions.vue b/src/components/account_actions/account_actions.vue index 770740e0b..9bcde9fed 100644 --- a/src/components/account_actions/account_actions.vue +++ b/src/components/account_actions/account_actions.vue @@ -29,6 +29,13 @@ /> + + @@ -40,6 +45,12 @@ line-height: 1.5em; } + &-button { + margin-top: 0.5em; + padding: 0 1.5em; + margin-left: 1em; + } + &-follow-button { margin-top: 0.5em; margin-left: auto; diff --git a/src/components/remove_follower_button/remove_follower_button.js b/src/components/remove_follower_button/remove_follower_button.js new file mode 100644 index 000000000..e1a7531bf --- /dev/null +++ b/src/components/remove_follower_button/remove_follower_button.js @@ -0,0 +1,25 @@ +export default { + props: ['relationship'], + data () { + return { + inProgress: false + } + }, + computed: { + label () { + if (this.inProgress) { + return this.$t('user_card.follow_progress') + } else { + return this.$t('user_card.remove_follower') + } + } + }, + methods: { + onClick () { + this.inProgress = true + this.$store.dispatch('removeUserFromFollowers', this.relationship.id).then(() => { + this.inProgress = false + }) + } + } +} diff --git a/src/components/remove_follower_button/remove_follower_button.vue b/src/components/remove_follower_button/remove_follower_button.vue new file mode 100644 index 000000000..a3a4c2426 --- /dev/null +++ b/src/components/remove_follower_button/remove_follower_button.vue @@ -0,0 +1,13 @@ + + + + + diff --git a/src/i18n/en.json b/src/i18n/en.json index ae63f6e67..22ec42a99 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -878,7 +878,7 @@ "muted": "Muted", "per_day": "per day", "remote_follow": "Remote follow", - "remove_this_follower": "Remove this follower", + "remove_follower": "Remove follower", "report": "Report", "statuses": "Statuses", "subscribe": "Subscribe", From 69b3102fb2396edb63abe98b4a69ebe311e22a70 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Sat, 14 Aug 2021 21:10:24 -0400 Subject: [PATCH 35/80] Group custom emojis by pack in emoji picker --- src/components/emoji_picker/emoji_picker.js | 29 ++++++++++++++----- src/components/emoji_picker/emoji_picker.scss | 13 +++++++++ src/components/emoji_picker/emoji_picker.vue | 10 +++++++ 3 files changed, 45 insertions(+), 7 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index f69202087..9e3981761 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -183,17 +183,32 @@ const EmojiPicker = { customEmojiBuffer () { return this.filteredEmoji.slice(0, this.customEmojiBufferSlice) }, + groupedCustomEmojis () { + const packOf = emoji => (emoji.tags.filter(k => k.startsWith('pack:'))[0] || '').slice(5) + return this.customEmojiBuffer.reduce((res, emoji) => { + const pack = packOf(emoji) + if (!res[pack]) { + res[pack] = { + id: `custom-${pack}`, + text: pack, + /// FIXME + // icon: 'smile-beam', + image: emoji.imageUrl, + emojis: [] + } + } + res[pack].emojis.push(emoji) + return res + }, {}) + }, emojis () { const standardEmojis = this.$store.state.instance.emoji || [] - const customEmojis = this.customEmojiBuffer + // const customEmojis = this.customEmojiBuffer return [ - { - id: 'custom', - text: this.$t('emoji.custom'), - icon: 'smile-beam', - emojis: customEmojis - }, + ...Object + .keys(this.groupedCustomEmojis) + .map(k => this.groupedCustomEmojis[k]), { id: 'standard', text: this.$t('emoji.unicode'), diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss index a2f17c514..ccb12a2a4 100644 --- a/src/components/emoji_picker/emoji_picker.scss +++ b/src/components/emoji_picker/emoji_picker.scss @@ -19,6 +19,19 @@ --lightText: var(--popoverLightText, $fallback--lightText); --icon: var(--popoverIcon, $fallback--icon); + &-header-image { + display: inline-flex; + justify-content: center; + align-items: center; + width: 30px; + height: 24px; + img { + max-width: 100%; + max-height: 100%; + object-fit: contain; + } + } + .keep-open, .too-many-emoji { padding: 7px; diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index a72691207..16549c08d 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -13,7 +13,17 @@ :title="group.text" @click.prevent="highlight(group.id)" > + + +
From ff2242e85dc89aa7479000cf469ca2bce5d60157 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Sat, 14 Aug 2021 21:23:45 -0400 Subject: [PATCH 36/80] Fix load more emoji action --- src/components/emoji_picker/emoji_picker.js | 5 ++++- src/modules/instance.js | 12 +++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 9e3981761..7d5a3d8f3 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -98,7 +98,7 @@ const EmojiPicker = { } }, triggerLoadMore (target) { - const ref = this.$refs['group-end-custom'] + const ref = this.$refs[`group-end-${this.lastNonUnicodeGroupId}`][0] if (!ref) return const bottom = ref.offsetTop + ref.offsetHeight @@ -217,6 +217,9 @@ const EmojiPicker = { } ] }, + lastNonUnicodeGroupId () { + return this.emojis[this.emojis.length - 2].id + }, emojisView () { return this.emojis.filter(value => value.emojis.length > 0) }, diff --git a/src/modules/instance.js b/src/modules/instance.js index bfce6f384..23f534c34 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -164,6 +164,16 @@ const instance = { if (res.ok) { const result = await res.json() const values = Array.isArray(result) ? Object.assign({}, ...result) : result + const caseInsensitiveStrCmp = (a, b) => { + const la = a.toLowerCase() + const lb = b.toLowerCase() + return la > lb ? 1 : (la < lb ? -1 : 0) + } + const byPackThenByName = (a, b) => { + const packOf = emoji => (emoji.tags.filter(k => k.startsWith('pack:'))[0] || '').slice(5) + return caseInsensitiveStrCmp(packOf(a), packOf(b)) || caseInsensitiveStrCmp(a.displayText, b.displayText) + } + const emoji = Object.entries(values).map(([key, value]) => { const imageUrl = value.image_url return { @@ -174,7 +184,7 @@ const instance = { } // Technically could use tags but those are kinda useless right now, // should have been "pack" field, that would be more useful - }).sort((a, b) => a.displayText.toLowerCase() > b.displayText.toLowerCase() ? 1 : -1) + }).sort(byPackThenByName) commit('setInstanceOption', { name: 'customEmoji', value: emoji }) } else { throw (res) From 992d57ef69540f4c63939fbc5abed9b1ea28ed2f Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Sat, 14 Aug 2021 21:50:58 -0400 Subject: [PATCH 37/80] Display all emoji groups on emoji picker header --- src/components/emoji_picker/emoji_picker.js | 28 +++++++++++++++++-- src/components/emoji_picker/emoji_picker.scss | 6 +++- src/components/emoji_picker/emoji_picker.vue | 4 +-- 3 files changed, 33 insertions(+), 5 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 7d5a3d8f3..d04649dcc 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -38,6 +38,8 @@ const filterByKeyword = (list, keyword = '') => { return orderedEmojiList.flat() } +const packOf = emoji => (emoji.tags.filter(k => k.startsWith('pack:'))[0] || '').slice(5) + const EmojiPicker = { props: { enableStickerPicker: { @@ -174,9 +176,12 @@ const EmojiPicker = { } return 0 }, + allEmojis () { + return this.$store.state.instance.customEmoji || [] + }, filteredEmoji () { return filterByKeyword( - this.$store.state.instance.customEmoji || [], + this.allEmojis, trim(this.keyword) ) }, @@ -184,7 +189,6 @@ const EmojiPicker = { return this.filteredEmoji.slice(0, this.customEmojiBufferSlice) }, groupedCustomEmojis () { - const packOf = emoji => (emoji.tags.filter(k => k.startsWith('pack:'))[0] || '').slice(5) return this.customEmojiBuffer.reduce((res, emoji) => { const pack = packOf(emoji) if (!res[pack]) { @@ -201,6 +205,26 @@ const EmojiPicker = { return res }, {}) }, + allEmojiGroups () { + return this.allEmojis + .reduce((res, emoji) => { + const packName = packOf(emoji) + const packId = `custom-${packName}` + if (res.filter(k => k.id === packId).length === 0) { + res.push({ + id: packId, + text: packName, + image: emoji.imageUrl + }) + } + return res + }, []) + .concat({ + id: 'standard', + text: this.$t('emoji.unicode'), + icon: 'box-open' + }) + }, emojis () { const standardEmojis = this.$store.state.instance.emoji || [] // const customEmojis = this.customEmojiBuffer diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss index ccb12a2a4..0bd4363cf 100644 --- a/src/components/emoji_picker/emoji_picker.scss +++ b/src/components/emoji_picker/emoji_picker.scss @@ -52,6 +52,7 @@ display: flex; height: 32px; padding: 10px 7px 5px; + overflow-x: auto; } .content { @@ -63,6 +64,9 @@ .emoji-tabs { flex-grow: 1; + display: flex; + flex-direction: row; + flex-wrap: nowrap; } .emoji-groups { @@ -70,6 +74,7 @@ } .additional-tabs { + display: block; border-left: 1px solid; border-left-color: $fallback--icon; border-left-color: var(--icon, $fallback--icon); @@ -79,7 +84,6 @@ .additional-tabs, .emoji-tabs { - display: block; min-width: 0; flex-basis: auto; flex-shrink: 1; diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index 16549c08d..fe60cb5ef 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -3,12 +3,12 @@ Date: Sat, 14 Aug 2021 23:37:00 -0400 Subject: [PATCH 38/80] Load visible emoji groups when scrolling --- src/components/emoji_picker/emoji_picker.js | 101 ++++++++++++++----- src/components/emoji_picker/emoji_picker.vue | 4 +- 2 files changed, 75 insertions(+), 30 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index d04649dcc..cab952f8e 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -57,7 +57,8 @@ const EmojiPicker = { keepOpen: false, customEmojiBufferSlice: LOAD_EMOJI_BY, customEmojiTimeout: null, - customEmojiLoadAllConfirmed: false + customEmojiLoadAllConfirmed: false, + groupLoadedCount: {} } }, components: { @@ -79,7 +80,9 @@ const EmojiPicker = { const target = (e && e.target) || this.$refs['emoji-groups'] this.updateScrolledClass(target) this.scrolledGroup(target) - this.triggerLoadMore(target) + this.$nextTick(() => { + this.triggerLoadMore(target) + }) }, highlight (key) { const ref = this.$refs['group-' + key] @@ -88,6 +91,7 @@ const EmojiPicker = { this.activeGroup = key this.$nextTick(() => { this.$refs['emoji-groups'].scrollTop = top + 1 + this.loadEmoji(key) }) }, updateScrolledClass (target) { @@ -100,28 +104,40 @@ const EmojiPicker = { } }, triggerLoadMore (target) { - const ref = this.$refs[`group-end-${this.lastNonUnicodeGroupId}`][0] - if (!ref) return - const bottom = ref.offsetTop + ref.offsetHeight + Object.keys(this.allCustomGroups) + .map(groupId => { + const ref = this.$refs[`group-end-${groupId}`][0] + if (!ref) return undefined - const scrollerBottom = target.scrollTop + target.clientHeight - const scrollerTop = target.scrollTop - const scrollerMax = target.scrollHeight + const bottom = ref.offsetTop + ref.offsetHeight - // Loads more emoji when they come into view - const approachingBottom = bottom - scrollerBottom < LOAD_EMOJI_MARGIN - // Always load when at the very top in case there's no scroll space yet - const atTop = scrollerTop < 5 - // Don't load when looking at unicode category or at the very bottom - const bottomAboveViewport = bottom < scrollerTop || scrollerBottom === scrollerMax - if (!bottomAboveViewport && (approachingBottom || atTop)) { - this.loadEmoji() - } + const group = this.$refs[`group-${groupId}`][0] + const top = group.offsetTop + + const scrollerBottom = target.scrollTop + target.clientHeight + const scrollerTop = target.scrollTop + const scrollerMax = target.scrollHeight + + // Loads more emoji when they come into view + const approachingBottom = bottom - scrollerBottom < LOAD_EMOJI_MARGIN + // Always load when at the very top in case there's no scroll space yet + const atTop = scrollerTop < top + target.clientHeight / 2 && top < scrollerBottom + // Don't load when looking at unicode category or at the very bottom + const bottomAboveViewport = bottom < scrollerTop || scrollerBottom === scrollerMax + if (!bottomAboveViewport && (approachingBottom || atTop)) { + return groupId + } + return undefined + }) + .filter(k => k) + .map(k => { + this.loadEmoji(k) + }) }, scrolledGroup (target) { const top = target.scrollTop + 5 this.$nextTick(() => { - this.emojisView.forEach(group => { + this.allEmojiGroups.forEach(group => { const ref = this.$refs['group-' + group.id] if (ref.offsetTop <= top) { this.activeGroup = group.id @@ -129,14 +145,21 @@ const EmojiPicker = { }) }) }, - loadEmoji () { - const allLoaded = this.customEmojiBuffer.length === this.filteredEmoji.length + loadEmoji (loadGroup) { + if (!this.allCustomGroups[loadGroup]) { + return + } + + const allLoaded = this.loadedCount[loadGroup] >= this.allCustomGroups[loadGroup].emojis.length if (allLoaded) { return } - this.customEmojiBufferSlice += LOAD_EMOJI_BY + this.groupLoadedCount = { + ...this.groupLoadedCount, + [loadGroup]: this.loadedCount[loadGroup] + LOAD_EMOJI_BY + } }, startEmojiLoad (forceUpdate = false) { if (!forceUpdate) { @@ -157,6 +180,9 @@ const EmojiPicker = { }, setShowStickers (value) { this.showingStickers = value + }, + limitedEmojis (list, groupId) { + return list.slice(0, this.loadedCount[groupId]) } }, watch: { @@ -205,24 +231,36 @@ const EmojiPicker = { return res }, {}) }, - allEmojiGroups () { - return this.allEmojis + allCustomGroups () { + return this.filteredEmoji .reduce((res, emoji) => { const packName = packOf(emoji) const packId = `custom-${packName}` - if (res.filter(k => k.id === packId).length === 0) { - res.push({ + if (!res[packId]) { + res[packId] = ({ id: packId, text: packName, - image: emoji.imageUrl + image: emoji.imageUrl, + emojis: [] }) } + res[packId].emojis.push(emoji) return res - }, []) + }, {}) + }, + sensibleInitialAmountForAGroup () { + const groupCount = Object.keys(this.allCustomGroups).length + return Math.max(Math.floor(LOAD_EMOJI_BY / Math.max(groupCount, 1)), 1) + }, + allEmojiGroups () { + const standardEmojis = this.$store.state.instance.emoji || [] + return Object.entries(this.allCustomGroups) + .map(([_, v]) => v) .concat({ id: 'standard', text: this.$t('emoji.unicode'), - icon: 'box-open' + icon: 'box-open', + emojis: filterByKeyword(standardEmojis, this.keyword) }) }, emojis () { @@ -241,6 +279,13 @@ const EmojiPicker = { } ] }, + loadedCount () { + return Object.keys(this.allCustomGroups) + .reduce((res, groupId) => { + res[groupId] = this.groupLoadedCount[groupId] || this.sensibleInitialAmountForAGroup + return res + }, {}) + }, lastNonUnicodeGroupId () { return this.emojis[this.emojis.length - 2].id }, diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index fe60cb5ef..277d5bf62 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -67,7 +67,7 @@ @scroll="onScroll" >@@ -78,7 +78,7 @@ {{ group.text }} Date: Sun, 15 Aug 2021 00:03:31 -0400 Subject: [PATCH 39/80] Load emoji properly on first showing --- src/components/emoji_picker/emoji_picker.js | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index cab952f8e..322bb8baa 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -58,7 +58,8 @@ const EmojiPicker = { customEmojiBufferSlice: LOAD_EMOJI_BY, customEmojiTimeout: null, customEmojiLoadAllConfirmed: false, - groupLoadedCount: {} + groupLoadedCount: {}, + firstLoaded: false } }, components: { @@ -167,6 +168,13 @@ const EmojiPicker = { } this.$nextTick(() => { this.$refs['emoji-groups'].scrollTop = 0 + this.$nextTick(() => { + if (this.firstLoaded) { + return + } + this.triggerLoadMore(this.$refs['emoji-groups']) + this.firstLoaded = true + }) }) const bufferSize = this.customEmojiBuffer.length const bufferPrefilledAll = bufferSize === this.filteredEmoji.length From 123913f34ffd91917a9ed4dd1c9d406fb547ef87 Mon Sep 17 00:00:00 2001 From: Tusooa ZhuDate: Sun, 15 Aug 2021 00:43:35 -0400 Subject: [PATCH 40/80] Optimise emoji picker loading process --- src/components/emoji_picker/emoji_picker.js | 83 ++++---------------- src/components/emoji_picker/emoji_picker.vue | 4 +- src/modules/instance.js | 18 +++++ 3 files changed, 34 insertions(+), 71 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 322bb8baa..67c6d0ccb 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -106,6 +106,7 @@ const EmojiPicker = { }, triggerLoadMore (target) { Object.keys(this.allCustomGroups) + .filter(id => this.filteredEmojiGroups.filter(group => group.id === id).length > 0) .map(groupId => { const ref = this.$refs[`group-end-${groupId}`][0] if (!ref) return undefined @@ -123,9 +124,10 @@ const EmojiPicker = { const approachingBottom = bottom - scrollerBottom < LOAD_EMOJI_MARGIN // Always load when at the very top in case there's no scroll space yet const atTop = scrollerTop < top + target.clientHeight / 2 && top < scrollerBottom + const unscrollable = top - bottom < target.clientHeight // Don't load when looking at unicode category or at the very bottom const bottomAboveViewport = bottom < scrollerTop || scrollerBottom === scrollerMax - if (!bottomAboveViewport && (approachingBottom || atTop)) { + if (!bottomAboveViewport && (approachingBottom || atTop || unscrollable)) { return groupId } return undefined @@ -176,12 +178,6 @@ const EmojiPicker = { this.firstLoaded = true }) }) - const bufferSize = this.customEmojiBuffer.length - const bufferPrefilledAll = bufferSize === this.filteredEmoji.length - if (bufferPrefilledAll && !forceUpdate) { - return - } - this.customEmojiBufferSlice = LOAD_EMOJI_BY }, toggleStickers () { this.showingStickers = !this.showingStickers @@ -191,6 +187,9 @@ const EmojiPicker = { }, limitedEmojis (list, groupId) { return list.slice(0, this.loadedCount[groupId]) + }, + filterByKeyword (list, keyword) { + return filterByKeyword(list, keyword) } }, watch: { @@ -210,51 +209,8 @@ const EmojiPicker = { } return 0 }, - allEmojis () { - return this.$store.state.instance.customEmoji || [] - }, - filteredEmoji () { - return filterByKeyword( - this.allEmojis, - trim(this.keyword) - ) - }, - customEmojiBuffer () { - return this.filteredEmoji.slice(0, this.customEmojiBufferSlice) - }, - groupedCustomEmojis () { - return this.customEmojiBuffer.reduce((res, emoji) => { - const pack = packOf(emoji) - if (!res[pack]) { - res[pack] = { - id: `custom-${pack}`, - text: pack, - /// FIXME - // icon: 'smile-beam', - image: emoji.imageUrl, - emojis: [] - } - } - res[pack].emojis.push(emoji) - return res - }, {}) - }, allCustomGroups () { - return this.filteredEmoji - .reduce((res, emoji) => { - const packName = packOf(emoji) - const packId = `custom-${packName}` - if (!res[packId]) { - res[packId] = ({ - id: packId, - text: packName, - image: emoji.imageUrl, - emojis: [] - }) - } - res[packId].emojis.push(emoji) - return res - }, {}) + return this.$store.getters.groupedCustomEmojis }, sensibleInitialAmountForAGroup () { const groupCount = Object.keys(this.allCustomGroups).length @@ -271,21 +227,13 @@ const EmojiPicker = { emojis: filterByKeyword(standardEmojis, this.keyword) }) }, - emojis () { - const standardEmojis = this.$store.state.instance.emoji || [] - // const customEmojis = this.customEmojiBuffer - - return [ - ...Object - .keys(this.groupedCustomEmojis) - .map(k => this.groupedCustomEmojis[k]), - { - id: 'standard', - text: this.$t('emoji.unicode'), - icon: 'box-open', - emojis: filterByKeyword(standardEmojis, trim(this.keyword)) - } - ] + filteredEmojiGroups () { + return this.allEmojiGroups + .map(group => ({ + ...group, + emojis: filterByKeyword(group.emojis, this.keyword) + })) + .filter(group => group.emojis.length > 0) }, loadedCount () { return Object.keys(this.allCustomGroups) @@ -297,9 +245,6 @@ const EmojiPicker = { lastNonUnicodeGroupId () { return this.emojis[this.emojis.length - 2].id }, - emojisView () { - return this.emojis.filter(value => value.emojis.length > 0) - }, stickerPickerEnabled () { return (this.$store.state.instance.stickers || []).length !== 0 } diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index 277d5bf62..7b2b7fc83 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -3,7 +3,7 @@ diff --git a/src/modules/instance.js b/src/modules/instance.js index 23f534c34..8aadce77e 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -115,6 +115,24 @@ const instance = { .map(key => [key, state[key]]) .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}) }, + groupedCustomEmojis (state) { + return state.customEmoji + .reduce((res, emoji) => { + emoji.tags.forEach(packName => { + const packId = `custom-${packName}` + if (!res[packId]) { + res[packId] = ({ + id: packId, + text: packName, + image: emoji.imageUrl, + emojis: [] + }) + } + res[packId].emojis.push(emoji) + }) + return res + }, {}) + }, instanceDomain (state) { return new URL(state.server).hostname } From 90f757cc6d9e1e29c2567979d3c27765f84cdc6c Mon Sep 17 00:00:00 2001 From: Tusooa ZhuDate: Sun, 15 Aug 2021 00:53:57 -0400 Subject: [PATCH 41/80] Lint --- src/components/emoji_picker/emoji_picker.js | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 67c6d0ccb..8e11f83f6 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -38,8 +38,6 @@ const filterByKeyword = (list, keyword = '') => { return orderedEmojiList.flat() } -const packOf = emoji => (emoji.tags.filter(k => k.startsWith('pack:'))[0] || '').slice(5) - const EmojiPicker = { props: { enableStickerPicker: { From c70cdbb873eb77bc1aaf7edb9defdda59bdba1e1 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Thu, 7 Oct 2021 23:23:58 -0400 Subject: [PATCH 42/80] Use lozad for lazy image loading Ref: grouped-emoji-picker --- package.json | 1 + src/components/emoji_picker/emoji_picker.js | 6 +++++- src/components/emoji_picker/emoji_picker.vue | 3 ++- src/directives/lazy_image_container.js | 13 +++++++++++++ yarn.lock | 5 +++++ 5 files changed, 26 insertions(+), 2 deletions(-) create mode 100644 src/directives/lazy_image_container.js diff --git a/package.json b/package.json index 50a6b55f8..06fb49163 100644 --- a/package.json +++ b/package.json @@ -35,6 +35,7 @@ "js-cookie": "3.0.1", "localforage": "1.10.0", "parse-link-header": "2.0.0", + "lozad": "^1.16.0", "phoenix": "1.6.2", "punycode.js": "2.1.0", "qrcode": "1.5.0", diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 8e11f83f6..82e5ad0b7 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -1,5 +1,6 @@ import { defineAsyncComponent } from 'vue' import Checkbox from '../checkbox/checkbox.vue' +import LazyImageContainer from '../../directives/lazy_image_container' import { library } from '@fortawesome/fontawesome-svg-core' import { faBoxOpen, @@ -64,6 +65,9 @@ const EmojiPicker = { StickerPicker: defineAsyncComponent(() => import('../sticker_picker/sticker_picker.vue')), Checkbox }, + directives: { + LazyImageContainer + }, methods: { onStickerUploaded (e) { this.$emit('sticker-uploaded', e) @@ -184,7 +188,7 @@ const EmojiPicker = { this.showingStickers = value }, limitedEmojis (list, groupId) { - return list.slice(0, this.loadedCount[groupId]) + return list // list.slice(0, this.loadedCount[groupId]) }, filterByKeyword (list, keyword) { return filterByKeyword(list, keyword) diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index 7b2b7fc83..0e6c7e41e 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -62,6 +62,7 @@ {{ emoji.replacement }}diff --git a/src/directives/lazy_image_container.js b/src/directives/lazy_image_container.js new file mode 100644 index 000000000..44adc828d --- /dev/null +++ b/src/directives/lazy_image_container.js @@ -0,0 +1,13 @@ + +import lozad from 'lozad' + +const LazyImageContainer = { + inserted (el) { + const images = el.querySelectorAll('img') + console.log(images.length) + el.$observer = lozad(images) + el.$observer.observe() + } +} + +export default LazyImageContainer diff --git a/yarn.lock b/yarn.lock index 2fefe76f2..041fc1dc4 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5733,6 +5733,11 @@ lower-case@^2.0.2: dependencies: tslib "^2.0.3" +lozad@^1.16.0: + version "1.16.0" + resolved "https://registry.yarnpkg.com/lozad/-/lozad-1.16.0.tgz#86ce732c64c69926ccdebb81c8c90bb3735948b4" + integrity sha512-JBr9WjvEFeKoyim3svo/gsQPTkgG/mOHJmDctZ/+U9H3ymUuvEkqpn8bdQMFsvTMcyRJrdJkLv0bXqGm0sP72w== + lru-cache@^6.0.0: version "6.0.0" resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-6.0.0.tgz#6d6fe6570ebd96aaf90fcad1dafa3b2566db3a94" From 8777b6eadd7deadf010dc36bb90514f75fc0da16 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu
Date: Fri, 8 Oct 2021 01:02:16 -0400 Subject: [PATCH 43/80] Clean up legacy code in emoji picker Ref: grouped-emoji-picker --- src/components/emoji_input/emoji_input.js | 1 - src/components/emoji_picker/emoji_picker.js | 130 ++++--------------- src/components/emoji_picker/emoji_picker.vue | 3 +- src/directives/lazy_image_container.js | 13 -- 4 files changed, 28 insertions(+), 119 deletions(-) delete mode 100644 src/directives/lazy_image_container.js diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js index b664d6b31..fb2096c93 100644 --- a/src/components/emoji_input/emoji_input.js +++ b/src/components/emoji_input/emoji_input.js @@ -207,7 +207,6 @@ const EmojiInput = { }, triggerShowPicker () { this.showPicker = true - this.$refs.picker.startEmojiLoad() this.$nextTick(() => { this.scrollIntoView() this.focusPickerInput() diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 82e5ad0b7..b0162479a 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -1,6 +1,6 @@ import { defineAsyncComponent } from 'vue' import Checkbox from '../checkbox/checkbox.vue' -import LazyImageContainer from '../../directives/lazy_image_container' +import lozad from 'lozad' import { library } from '@fortawesome/fontawesome-svg-core' import { faBoxOpen, @@ -54,7 +54,6 @@ const EmojiPicker = { showingStickers: false, groupsScrolledClass: 'scrolled-top', keepOpen: false, - customEmojiBufferSlice: LOAD_EMOJI_BY, customEmojiTimeout: null, customEmojiLoadAllConfirmed: false, groupLoadedCount: {}, @@ -65,9 +64,6 @@ const EmojiPicker = { StickerPicker: defineAsyncComponent(() => import('../sticker_picker/sticker_picker.vue')), Checkbox }, - directives: { - LazyImageContainer - }, methods: { onStickerUploaded (e) { this.$emit('sticker-uploaded', e) @@ -82,10 +78,6 @@ const EmojiPicker = { onScroll (e) { const target = (e && e.target) || this.$refs['emoji-groups'] this.updateScrolledClass(target) - this.scrolledGroup(target) - this.$nextTick(() => { - this.triggerLoadMore(target) - }) }, highlight (key) { const ref = this.$refs['group-' + key] @@ -94,7 +86,6 @@ const EmojiPicker = { this.activeGroup = key this.$nextTick(() => { this.$refs['emoji-groups'].scrollTop = top + 1 - this.loadEmoji(key) }) }, updateScrolledClass (target) { @@ -106,101 +97,48 @@ const EmojiPicker = { this.groupsScrolledClass = 'scrolled-middle' } }, - triggerLoadMore (target) { - Object.keys(this.allCustomGroups) - .filter(id => this.filteredEmojiGroups.filter(group => group.id === id).length > 0) - .map(groupId => { - const ref = this.$refs[`group-end-${groupId}`][0] - if (!ref) return undefined - - const bottom = ref.offsetTop + ref.offsetHeight - - const group = this.$refs[`group-${groupId}`][0] - const top = group.offsetTop - - const scrollerBottom = target.scrollTop + target.clientHeight - const scrollerTop = target.scrollTop - const scrollerMax = target.scrollHeight - - // Loads more emoji when they come into view - const approachingBottom = bottom - scrollerBottom < LOAD_EMOJI_MARGIN - // Always load when at the very top in case there's no scroll space yet - const atTop = scrollerTop < top + target.clientHeight / 2 && top < scrollerBottom - const unscrollable = top - bottom < target.clientHeight - // Don't load when looking at unicode category or at the very bottom - const bottomAboveViewport = bottom < scrollerTop || scrollerBottom === scrollerMax - if (!bottomAboveViewport && (approachingBottom || atTop || unscrollable)) { - return groupId - } - return undefined - }) - .filter(k => k) - .map(k => { - this.loadEmoji(k) - }) - }, - scrolledGroup (target) { - const top = target.scrollTop + 5 - this.$nextTick(() => { - this.allEmojiGroups.forEach(group => { - const ref = this.$refs['group-' + group.id] - if (ref.offsetTop <= top) { - this.activeGroup = group.id - } - }) - }) - }, - loadEmoji (loadGroup) { - if (!this.allCustomGroups[loadGroup]) { - return - } - - const allLoaded = this.loadedCount[loadGroup] >= this.allCustomGroups[loadGroup].emojis.length - - if (allLoaded) { - return - } - - this.groupLoadedCount = { - ...this.groupLoadedCount, - [loadGroup]: this.loadedCount[loadGroup] + LOAD_EMOJI_BY - } - }, - startEmojiLoad (forceUpdate = false) { - if (!forceUpdate) { - this.keyword = '' - } - this.$nextTick(() => { - this.$refs['emoji-groups'].scrollTop = 0 - this.$nextTick(() => { - if (this.firstLoaded) { - return - } - this.triggerLoadMore(this.$refs['emoji-groups']) - this.firstLoaded = true - }) - }) - }, toggleStickers () { this.showingStickers = !this.showingStickers }, setShowStickers (value) { this.showingStickers = value }, - limitedEmojis (list, groupId) { - return list // list.slice(0, this.loadedCount[groupId]) - }, filterByKeyword (list, keyword) { return filterByKeyword(list, keyword) + }, + initializeLazyLoad () { + this.destroyLazyLoad() + this.$lozad = lozad('img', {}) + this.$lozad.observe() + }, + destroyLazyLoad () { + if (this.$lozad) { + if (this.$lozad.observer) { + this.$lozad.observer.disconnect() + } + if (this.$lozad.mutationObserver) { + this.$lozad.mutationObserver.disconnect() + } + } } }, watch: { keyword () { this.customEmojiLoadAllConfirmed = false this.onScroll() - this.startEmojiLoad(true) + // Wait for the dom to change + this.$nextTick(() => this.initializeLazyLoad()) + }, + allCustomGroups () { + this.$nextTick(() => this.initializeLazyLoad()) } }, + mounted () { + this.initializeLazyLoad() + }, + destroyed () { + this.destroyLazyLoad() + }, computed: { activeGroupView () { return this.showingStickers ? '' : this.activeGroup @@ -214,10 +152,6 @@ const EmojiPicker = { allCustomGroups () { return this.$store.getters.groupedCustomEmojis }, - sensibleInitialAmountForAGroup () { - const groupCount = Object.keys(this.allCustomGroups).length - return Math.max(Math.floor(LOAD_EMOJI_BY / Math.max(groupCount, 1)), 1) - }, allEmojiGroups () { const standardEmojis = this.$store.state.instance.emoji || [] return Object.entries(this.allCustomGroups) @@ -237,16 +171,6 @@ const EmojiPicker = { })) .filter(group => group.emojis.length > 0) }, - loadedCount () { - return Object.keys(this.allCustomGroups) - .reduce((res, groupId) => { - res[groupId] = this.groupLoadedCount[groupId] || this.sensibleInitialAmountForAGroup - return res - }, {}) - }, - lastNonUnicodeGroupId () { - return this.emojis[this.emojis.length - 2].id - }, stickerPickerEnabled () { return (this.$store.state.instance.stickers || []).length !== 0 } diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index 0e6c7e41e..0df33c241 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -62,7 +62,6 @@ Date: Fri, 8 Oct 2021 01:11:32 -0400 Subject: [PATCH 44/80] Fix scrol->highlight behaviour Ref: grouped-emoji-picker --- src/components/emoji_picker/emoji_picker.js | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index b0162479a..31a455fde 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -78,6 +78,18 @@ const EmojiPicker = { onScroll (e) { const target = (e && e.target) || this.$refs['emoji-groups'] this.updateScrolledClass(target) + this.scrolledGroup(target) + }, + scrolledGroup (target) { + const top = target.scrollTop + 5 + this.$nextTick(() => { + this.allEmojiGroups.forEach(group => { + const ref = this.$refs['group-' + group.id] + if (ref[0].offsetTop <= top) { + this.activeGroup = group.id + } + }) + }) }, highlight (key) { const ref = this.$refs['group-' + key] @@ -134,6 +146,9 @@ const EmojiPicker = { } }, mounted () { + if (this.defaultGroup) { + this.highlight(this.defaultGroup) + } this.initializeLazyLoad() }, destroyed () { @@ -152,6 +167,9 @@ const EmojiPicker = { allCustomGroups () { return this.$store.getters.groupedCustomEmojis }, + defaultGroup () { + return Object.keys(this.allCustomGroups)[0] + }, allEmojiGroups () { const standardEmojis = this.$store.state.instance.emoji || [] return Object.entries(this.allCustomGroups) From f1d6e6afce6a0a6d709ae6ede5f14bdf3cf48e2b Mon Sep 17 00:00:00 2001 From: Tusooa ZhuDate: Fri, 8 Oct 2021 01:20:35 -0400 Subject: [PATCH 45/80] Clean up unused variables Ref: grouped-emoji-picker --- src/components/emoji_picker/emoji_picker.js | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 31a455fde..d60daab76 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -15,13 +15,6 @@ library.add( faSmileBeam ) -// At widest, approximately 20 emoji are visible in a row, -// loading 3 rows, could be overkill for narrow picker -const LOAD_EMOJI_BY = 60 - -// When to start loading new batch emoji, in pixels -const LOAD_EMOJI_MARGIN = 64 - const filterByKeyword = (list, keyword = '') => { if (keyword === '') return list @@ -54,10 +47,7 @@ const EmojiPicker = { showingStickers: false, groupsScrolledClass: 'scrolled-top', keepOpen: false, - customEmojiTimeout: null, - customEmojiLoadAllConfirmed: false, - groupLoadedCount: {}, - firstLoaded: false + customEmojiTimeout: null } }, components: { @@ -136,7 +126,6 @@ const EmojiPicker = { }, watch: { keyword () { - this.customEmojiLoadAllConfirmed = false this.onScroll() // Wait for the dom to change this.$nextTick(() => this.initializeLazyLoad()) From 031a01be7920e4cf3bda6ed5e4f3e589f9821121 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Fri, 8 Oct 2021 13:06:03 -0400 Subject: [PATCH 46/80] Remove useless class `disabled` in emoji picker Ref: grouped-emoji-picker --- src/components/emoji_picker/emoji_picker.vue | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index 0df33c241..fb2eef250 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -7,8 +7,7 @@ :key="group.id" class="emoji-tabs-item" :class="{ - active: activeGroupView === group.id, - disabled: false + active: activeGroupView === group.id }" :title="group.text" @click.prevent="highlight(group.id)" From 5ab51613b738bf089770c2ad6d0ae9354d49bcee Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Fri, 8 Oct 2021 13:17:47 -0400 Subject: [PATCH 47/80] Use StillImage for emoji group header Ref: grouped-emoji-picker --- src/components/emoji_picker/emoji_picker.js | 4 +++- src/components/emoji_picker/emoji_picker.vue | 4 ++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index d60daab76..5b90c31e7 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -1,5 +1,6 @@ import { defineAsyncComponent } from 'vue' import Checkbox from '../checkbox/checkbox.vue' +import StillImage from '../still-image/still-image.vue' import lozad from 'lozad' import { library } from '@fortawesome/fontawesome-svg-core' import { @@ -52,7 +53,8 @@ const EmojiPicker = { }, components: { StickerPicker: defineAsyncComponent(() => import('../sticker_picker/sticker_picker.vue')), - Checkbox + Checkbox, + StillImage }, methods: { onStickerUploaded (e) { diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index fb2eef250..ed196066d 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -16,10 +16,10 @@ v-if="group.image" class="emoji-picker-header-image" > - + />
Date: Fri, 8 Oct 2021 14:10:17 -0400 Subject: [PATCH 48/80] Fix vertical scrollbar of emoji picker header Ref: grouped-emoji-picker --- src/components/emoji_picker/emoji_picker.scss | 29 ++++++++++++++----- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss index 0bd4363cf..e315d2d7f 100644 --- a/src/components/emoji_picker/emoji_picker.scss +++ b/src/components/emoji_picker/emoji_picker.scss @@ -1,5 +1,10 @@ @import '../../_variables.scss'; +$emoji-picker-header-height: 36px; +$emoji-picker-header-picture-width: 32px; +$emoji-picker-header-picture-height: 32px; +$emoji-picker-emoji-size: 32px; + .emoji-picker { display: flex; flex-direction: column; @@ -23,9 +28,11 @@ display: inline-flex; justify-content: center; align-items: center; - width: 30px; - height: 24px; - img { + width: $emoji-picker-header-picture-width; + max-width: $emoji-picker-header-picture-width; + height: $emoji-picker-header-picture-height; + max-height: $emoji-picker-header-picture-height; + .still-image { max-width: 100%; max-height: 100%; object-fit: contain; @@ -50,7 +57,7 @@ .heading { display: flex; - height: 32px; + //height: $emoji-picker-header-height; padding: 10px 7px 5px; overflow-x: auto; } @@ -87,11 +94,19 @@ min-width: 0; flex-basis: auto; flex-shrink: 1; + display: flex; + align-content: center; &-item { padding: 0 7px; cursor: pointer; font-size: 1.85em; + width: $emoji-picker-header-picture-width; + max-width: $emoji-picker-header-picture-width; + height: $emoji-picker-header-picture-height; + max-height: $emoji-picker-header-picture-height; + display: flex; + align-items: center; &.disabled { opacity: 0.5; @@ -181,11 +196,11 @@ } &-item { - width: 32px; - height: 32px; + width: $emoji-picker-emoji-size; + height: $emoji-picker-emoji-size; box-sizing: border-box; display: flex; - font-size: 32px; + font-size: $emoji-picker-emoji-size; align-items: center; justify-content: center; margin: 4px; From 9aeffd7634e049123d3ffc8addf9c223652b0bbb Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Fri, 8 Oct 2021 14:46:00 -0400 Subject: [PATCH 49/80] Fix sticker picker heading tab Ref: grouped-emoji-picker --- src/components/emoji_picker/emoji_picker.scss | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss index e315d2d7f..ea8b60378 100644 --- a/src/components/emoji_picker/emoji_picker.scss +++ b/src/components/emoji_picker/emoji_picker.scss @@ -57,9 +57,7 @@ $emoji-picker-emoji-size: 32px; .heading { display: flex; - //height: $emoji-picker-header-height; padding: 10px 7px 5px; - overflow-x: auto; } .content { @@ -74,6 +72,7 @@ $emoji-picker-emoji-size: 32px; display: flex; flex-direction: row; flex-wrap: nowrap; + overflow-x: auto; } .emoji-groups { @@ -81,7 +80,8 @@ $emoji-picker-emoji-size: 32px; } .additional-tabs { - display: block; + display: flex; + flex: 1; border-left: 1px solid; border-left-color: $fallback--icon; border-left-color: var(--icon, $fallback--icon); @@ -91,9 +91,8 @@ $emoji-picker-emoji-size: 32px; .additional-tabs, .emoji-tabs { - min-width: 0; flex-basis: auto; - flex-shrink: 1; + // flex-shrink: 1; display: flex; align-content: center; From 06a636db3732ce2808c54d3b74eb4aabd866dbf6 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Fri, 8 Oct 2021 15:09:24 -0400 Subject: [PATCH 50/80] Lazy-load emoji picker in post form When clicking the reply button, we used to load the whole emoji picker. This causes a considerable delay even if the user is not going to use the emoji picker. Now the content of the emoji picker is loaded only after the user has explicitly opened the emoji picker. Ref: grouped-emoji-picker --- src/components/emoji_input/emoji_input.vue | 1 + src/components/emoji_picker/emoji_picker.js | 24 ++++++++++++++++---- src/components/emoji_picker/emoji_picker.vue | 9 ++++++-- 3 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/components/emoji_input/emoji_input.vue b/src/components/emoji_input/emoji_input.vue index 81b819132..eedde9aa2 100644 --- a/src/components/emoji_input/emoji_input.vue +++ b/src/components/emoji_input/emoji_input.vue @@ -19,6 +19,7 @@ v-if="enableEmojiPicker" ref="picker" :class="{ hide: !showPicker }" + :showing="showPicker" :enable-sticker-picker="enableStickerPicker" class="emoji-picker-panel" @emoji="insert" diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 5b90c31e7..8b4f302f8 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -39,6 +39,10 @@ const EmojiPicker = { required: false, type: Boolean, default: false + }, + showing: { + required: true, + type: Boolean } }, data () { @@ -48,7 +52,9 @@ const EmojiPicker = { showingStickers: false, groupsScrolledClass: 'scrolled-top', keepOpen: false, - customEmojiTimeout: null + customEmojiTimeout: null, + // Lazy-load only after the first time `showing` becomes true. + contentLoaded: false } }, components: { @@ -115,6 +121,9 @@ const EmojiPicker = { this.$lozad = lozad('img', {}) this.$lozad.observe() }, + waitForDomAndInitializeLazyLoad() { + this.$nextTick(() => this.initializeLazyLoad()) + }, destroyLazyLoad () { if (this.$lozad) { if (this.$lozad.observer) { @@ -129,18 +138,23 @@ const EmojiPicker = { watch: { keyword () { this.onScroll() - // Wait for the dom to change - this.$nextTick(() => this.initializeLazyLoad()) + this.waitForDomAndInitializeLazyLoad() }, allCustomGroups () { - this.$nextTick(() => this.initializeLazyLoad()) + this.waitForDomAndInitializeLazyLoad() + }, + showing (val) { + if (val) { + this.contentLoaded = true + this.waitForDomAndInitializeLazyLoad() + } } }, mounted () { if (this.defaultGroup) { this.highlight(this.defaultGroup) } - this.initializeLazyLoad() + this.waitForDomAndInitializeLazyLoad() }, destroyed () { this.destroyLazyLoad() diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index ed196066d..b92bccd74 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -1,5 +1,7 @@ - +-+Date: Fri, 8 Oct 2021 15:25:13 -0400 Subject: [PATCH 51/80] Lint Ref: grouped-emoji-picker --- src/components/emoji_picker/emoji_picker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 8b4f302f8..aeee867d4 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -121,7 +121,7 @@ const EmojiPicker = { this.$lozad = lozad('img', {}) this.$lozad.observe() }, - waitForDomAndInitializeLazyLoad() { + waitForDomAndInitializeLazyLoad () { this.$nextTick(() => this.initializeLazyLoad()) }, destroyLazyLoad () { From d648a6f8dc37a2ceb851f1cecde34fd6c54d7d1f Mon Sep 17 00:00:00 2001 From: Tusooa Zhudiff --git a/src/components/still-image/still-image.js b/src/components/still-image/still-image.js index d7abbcb5e..1806d33b0 100644 --- a/src/components/still-image/still-image.js +++ b/src/components/still-image/still-image.js @@ -7,16 +7,23 @@ const StillImage = { 'imageLoadHandler', 'alt', 'height', - 'width' + 'width', + 'dataSrc' ], data () { return { + // for lazy loading, see loadLazy() + realSrc: this.src, stopGifs: this.$store.getters.mergedConfig.stopGifs } }, computed: { animated () { - return this.stopGifs && (this.mimetype === 'image/gif' || this.src.endsWith('.gif')) + if (!this.realSrc) { + return false + } + + return this.stopGifs && (this.mimetype === 'image/gif' || this.realSrc.endsWith('.gif')) }, style () { const appendPx = (str) => /\d$/.test(str) ? str + 'px' : str @@ -27,7 +34,15 @@ const StillImage = { } }, methods: { + loadLazy () { + if (this.dataSrc) { + this.realSrc = this.dataSrc + } + }, onLoad () { + if (!this.realSrc) { + return + } const image = this.$refs.src if (!image) return this.imageLoadHandler && this.imageLoadHandler(image) diff --git a/src/components/still-image/still-image.vue b/src/components/still-image/still-image.vue index ab3080c8c..633fb229b 100644 --- a/src/components/still-image/still-image.vue +++ b/src/components/still-image/still-image.vue @@ -11,10 +11,11 @@Date: Fri, 8 Oct 2021 15:30:55 -0400 Subject: [PATCH 52/80] Group emojis only by pack and remove pack: prefix Ref: grouped-emoji-picker --- src/modules/instance.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/modules/instance.js b/src/modules/instance.js index 8aadce77e..a7a91d99c 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -116,9 +116,15 @@ const instance = { .reduce((acc, [key, value]) => ({ ...acc, [key]: value }), {}) }, groupedCustomEmojis (state) { + const packsOf = emoji => { + return emoji.tags + .filter(k => k.startsWith('pack:')) + .map(k => k.slice(5)) // remove 'pack:' prefix + } + return state.customEmoji .reduce((res, emoji) => { - emoji.tags.forEach(packName => { + packsOf(emoji).forEach(packName => { const packId = `custom-${packName}` if (!res[packId]) { res[packId] = ({ From c93da0b865e9a14c6fa952e63c4c4f77f34943bc Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Fri, 8 Oct 2021 15:47:39 -0400 Subject: [PATCH 53/80] Fix error on emoji picker first load Ref: grouped-emoji-picker --- src/components/emoji_picker/emoji_picker.js | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index aeee867d4..ea53a972a 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -133,6 +133,18 @@ const EmojiPicker = { this.$lozad.mutationObserver.disconnect() } } + }, + onShowing () { + const oldContentLoaded = this.contentLoaded + this.contentLoaded = true + this.waitForDomAndInitializeLazyLoad() + if (!oldContentLoaded) { + this.$nextTick(() => { + if (this.defaultGroup) { + this.highlight(this.defaultGroup) + } + }) + } } }, watch: { @@ -145,16 +157,14 @@ const EmojiPicker = { }, showing (val) { if (val) { - this.contentLoaded = true - this.waitForDomAndInitializeLazyLoad() + this.onShowing() } } }, mounted () { - if (this.defaultGroup) { - this.highlight(this.defaultGroup) + if (this.showing) { + this.onShowing() } - this.waitForDomAndInitializeLazyLoad() }, destroyed () { this.destroyLazyLoad() From b77259a9a0c353ede8ff1d6bf5c13ae91ca7fc7c Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Sat, 8 Jan 2022 01:35:16 -0500 Subject: [PATCH 54/80] Use StillImage to render emojis in emoji picker --- src/components/emoji_picker/emoji_picker.js | 15 +++++++++++++-- src/components/emoji_picker/emoji_picker.vue | 5 +++-- src/components/still-image/still-image.js | 19 +++++++++++++++++-- src/components/still-image/still-image.vue | 5 +++-- 4 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index ea53a972a..315364d5b 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -118,8 +118,19 @@ const EmojiPicker = { }, initializeLazyLoad () { this.destroyLazyLoad() - this.$lozad = lozad('img', {}) - this.$lozad.observe() + this.$nextTick(() => { + this.$lozad = lozad('.still-image.emoji-picker-emoji', { + load: el => { + const vn = el.__vue__ + if (!vn) { + return + } + + vn.loadLazy() + } + }) + this.$lozad.observe() + }) }, waitForDomAndInitializeLazyLoad () { this.$nextTick(() => this.initializeLazyLoad()) diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index b92bccd74..19cc46b54 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -89,10 +89,11 @@ @click.stop.prevent="onEmoji(emoji)" > {{ emoji.replacement }} - + />
Date: Sat, 8 Jan 2022 01:37:19 -0500 Subject: [PATCH 55/80] Clean up emoji picker css --- src/components/emoji_picker/emoji_picker.scss | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss index ea8b60378..222749d01 100644 --- a/src/components/emoji_picker/emoji_picker.scss +++ b/src/components/emoji_picker/emoji_picker.scss @@ -92,7 +92,6 @@ $emoji-picker-emoji-size: 32px; .additional-tabs, .emoji-tabs { flex-basis: auto; - // flex-shrink: 1; display: flex; align-content: center; From 38861fc6cc1e30c6ef3c429db222a303ed1c321d Mon Sep 17 00:00:00 2001 From: Tusooa Zhu
Date: Sat, 8 Jan 2022 02:17:59 -0500 Subject: [PATCH 56/80] Scroll active tab header into view in emoji picker --- src/components/emoji_picker/emoji_picker.js | 18 ++++++++++++++++++ src/components/emoji_picker/emoji_picker.vue | 6 +++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 315364d5b..26c767ac4 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -87,8 +87,26 @@ const EmojiPicker = { this.activeGroup = group.id } }) + this.scrollHeader() }) }, + scrollHeader () { + // Scroll the active tab's header into view + const headerRef = this.$refs['group-header-' + this.activeGroup][0] + const left = headerRef.offsetLeft + const right = left + headerRef.offsetWidth + const headerCont = this.$refs.header + const currentScroll = headerCont.scrollLeft + const currentScrollRight = currentScroll + headerCont.clientWidth + const setScroll = s => { headerCont.scrollLeft = s } + + const margin = 7 // .emoji-tabs-item: padding + if (left - margin < currentScroll) { + setScroll(left - margin) + } else if (right + margin > currentScrollRight) { + setScroll(right + margin - headerCont.clientWidth) + } + }, highlight (key) { const ref = this.$refs['group-' + key] const top = ref.offsetTop diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index 19cc46b54..e8d42c243 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -3,9 +3,13 @@ class="emoji-picker panel panel-default panel-body" > - + Date: Sat, 8 Jan 2022 16:55:00 -0500 Subject: [PATCH 58/80] Make emoji picker use grouped unicode emojis --- src/components/emoji_input/suggestor.js | 2 +- src/components/emoji_picker/emoji_picker.js | 16 ++++---- .../post_status_form/post_status_form.js | 6 +-- src/components/react_button/react_button.js | 4 +- .../settings_modal/tabs/profile_tab.js | 4 +- src/modules/instance.js | 38 +++++++++++++++---- 6 files changed, 48 insertions(+), 22 deletions(-) diff --git a/src/components/emoji_input/suggestor.js b/src/components/emoji_input/suggestor.js index 0ddb4d689..1765f8438 100644 --- a/src/components/emoji_input/suggestor.js +++ b/src/components/emoji_input/suggestor.js @@ -2,7 +2,7 @@ * suggest - generates a suggestor function to be used by emoji-input * data: object providing source information for specific types of suggestions: * data.emoji - optional, an array of all emoji available i.e. - * (state.instance.emoji + state.instance.customEmoji) + * (getters.standardEmojiList + state.instance.customEmoji) * data.users - optional, an array of all known users * updateUsersList - optional, a function to search and append to users * diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 26c767ac4..4990afb3e 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -214,16 +214,18 @@ const EmojiPicker = { defaultGroup () { return Object.keys(this.allCustomGroups)[0] }, + unicodeEmojiGroups () { + return this.$store.getters.standardEmojiGroupList.map(group => ({ + id: `standard-${group.id}`, + text: this.$t(`emoji.unicode_groups.${group.id}`), + icon: 'box-open', + emojis: group.emojis + })) + }, allEmojiGroups () { - const standardEmojis = this.$store.state.instance.emoji || [] return Object.entries(this.allCustomGroups) .map(([_, v]) => v) - .concat({ - id: 'standard', - text: this.$t('emoji.unicode'), - icon: 'box-open', - emojis: filterByKeyword(standardEmojis, this.keyword) - }) + .concat(this.unicodeEmojiGroups) }, filteredEmojiGroups () { return this.allEmojiGroups diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 77f73d046..5c536b749 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -189,7 +189,7 @@ const PostStatusForm = { emojiUserSuggestor () { return suggestor({ emoji: [ - ...this.$store.state.instance.emoji, + ...this.$store.getters.standardEmojiList, ...this.$store.state.instance.customEmoji ], store: this.$store @@ -198,13 +198,13 @@ const PostStatusForm = { emojiSuggestor () { return suggestor({ emoji: [ - ...this.$store.state.instance.emoji, + ...this.$store.getters.standardEmojiList, ...this.$store.state.instance.customEmoji ] }) }, emoji () { - return this.$store.state.instance.emoji || [] + return this.$store.getters.standardEmojiList || [] }, customEmoji () { return this.$store.state.instance.customEmoji || [] diff --git a/src/components/react_button/react_button.js b/src/components/react_button/react_button.js index 5e052e1e0..e65bfd932 100644 --- a/src/components/react_button/react_button.js +++ b/src/components/react_button/react_button.js @@ -59,7 +59,7 @@ const ReactButton = { if (this.filterWord !== '') { const filterWordLowercase = trim(this.filterWord.toLowerCase()) const orderedEmojiList = [] - for (const emoji of this.$store.state.instance.emoji) { + for (const emoji of this.$store.getters.standardEmojiList) { if (emoji.replacement === this.filterWord) return [emoji] const indexOfFilterWord = emoji.displayText.toLowerCase().indexOf(filterWordLowercase) @@ -72,7 +72,7 @@ const ReactButton = { } return orderedEmojiList.flat() } - return this.$store.state.instance.emoji || [] + return this.$store.getters.standardEmojiList || [] }, mergedConfig () { return this.$store.getters.mergedConfig diff --git a/src/components/settings_modal/tabs/profile_tab.js b/src/components/settings_modal/tabs/profile_tab.js index 376248efd..b86faef0e 100644 --- a/src/components/settings_modal/tabs/profile_tab.js +++ b/src/components/settings_modal/tabs/profile_tab.js @@ -64,7 +64,7 @@ const ProfileTab = { emojiUserSuggestor () { return suggestor({ emoji: [ - ...this.$store.state.instance.emoji, + ...this.$store.getters.standardEmojiList, ...this.$store.state.instance.customEmoji ], store: this.$store @@ -73,7 +73,7 @@ const ProfileTab = { emojiSuggestor () { return suggestor({ emoji: [ - ...this.$store.state.instance.emoji, + ...this.$store.getters.standardEmojiList, ...this.$store.state.instance.customEmoji ] }) diff --git a/src/modules/instance.js b/src/modules/instance.js index a7a91d99c..2fcb059c5 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -3,6 +3,18 @@ import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js' import apiService from '../services/api/api.service.js' import { instanceDefaultProperties } from './config.js' +const SORTED_EMOJI_GROUP_IDS = [ + 'smileys-and-emotion', + 'people-and-body', + 'animals-and-nature', + 'food-and-drink', + 'travel-and-places', + 'activities', + 'objects', + 'symbols', + 'flags' +] + const defaultState = { // Stuff from apiConfig name: 'Pleroma FE', @@ -64,7 +76,7 @@ const defaultState = { // Nasty stuff customEmoji: [], customEmojiFetched: false, - emoji: [], + emoji: {}, emojiFetched: false, pleromaBackend: true, postFormats: [], @@ -139,6 +151,17 @@ const instance = { return res }, {}) }, + standardEmojiList (state) { + return SORTED_EMOJI_GROUP_IDS + .map(groupId => state.emoji[groupId] || []) + .reduce((a, b) => a.concat(b), []) + }, + standardEmojiGroupList (state) { + return SORTED_EMOJI_GROUP_IDS.map(groupId => ({ + id: groupId, + emojis: state.emoji[groupId] || [] + })) + }, instanceDomain (state) { return new URL(state.server).hostname } @@ -165,13 +188,14 @@ const instance = { const res = await window.fetch('/static/emoji.json') if (res.ok) { const values = await res.json() - const emoji = Object.keys(values).map((key) => { - return { - displayText: key, + const emoji = Object.keys(values).reduce((res, groupId) => { + res[groupId] = values[groupId].map(e => ({ + displayText: e.name, imageUrl: false, - replacement: values[key] - } - }).sort((a, b) => a.name > b.name ? 1 : -1) + replacement: e.emoji + })) + return res + }, {}) commit('setInstanceOption', { name: 'emoji', value: emoji }) } else { throw (res) From 02de0ed825667c5a40be5c18b86f71152198e77a Mon Sep 17 00:00:00 2001 From: Tusooa ZhuDate: Sat, 8 Jan 2022 17:14:23 -0500 Subject: [PATCH 59/80] Add icons for unicode emoji groups --- src/components/emoji_picker/emoji_picker.js | 36 +++++++++++++++++++-- 1 file changed, 33 insertions(+), 3 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 4990afb3e..bf4a98d4d 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -6,16 +6,46 @@ import { library } from '@fortawesome/fontawesome-svg-core' import { faBoxOpen, faStickyNote, - faSmileBeam + faSmileBeam, + faSmile, + faUser, + faPaw, + faIceCream, + faBus, + faBasketballBall, + faLightbulb, + faCode, + faFlag } from '@fortawesome/free-solid-svg-icons' import { trim } from 'lodash' library.add( faBoxOpen, faStickyNote, - faSmileBeam + faSmileBeam, + faSmile, + faUser, + faPaw, + faIceCream, + faBus, + faBasketballBall, + faLightbulb, + faCode, + faFlag ) +const UNICODE_EMOJI_GROUP_ICON = { + 'smileys-and-emotion': 'smile', + 'people-and-body': 'user', + 'animals-and-nature': 'paw', + 'food-and-drink': 'ice-cream', + 'travel-and-places': 'bus', + 'activities': 'basketball-ball', + 'objects': 'lightbulb', + 'symbols': 'code', + 'flags': 'flag', +} + const filterByKeyword = (list, keyword = '') => { if (keyword === '') return list @@ -218,7 +248,7 @@ const EmojiPicker = { return this.$store.getters.standardEmojiGroupList.map(group => ({ id: `standard-${group.id}`, text: this.$t(`emoji.unicode_groups.${group.id}`), - icon: 'box-open', + icon: UNICODE_EMOJI_GROUP_ICON[group.id], emojis: group.emojis })) }, From a29ac5b9a4ad50b2b840172e574c57463c30e383 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Sat, 8 Jan 2022 17:16:48 -0500 Subject: [PATCH 60/80] Add English translation for unicode emoji group names --- src/i18n/en.json | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/src/i18n/en.json b/src/i18n/en.json index 1d494d4a2..2a665bd59 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -199,6 +199,17 @@ "add_emoji": "Insert emoji", "custom": "Custom emoji", "unicode": "Unicode emoji", + "unicode_groups": { + "activities": "Activities", + "animals-and-nature": "Animals & Nature", + "flags": "Flags", + "food-and-drink": "Food & Drink", + "objects": "Objects", + "people-and-body": "People & Body", + "smileys-and-emotion": "Smileys & Emotion", + "symbols": "Symbols", + "travel-and-places": "Travel & Places" + }, "load_all_hint": "Loaded first {saneAmount} emoji, loading all emoji may cause performance issues.", "load_all": "Loading all {emojiAmount} emoji" }, From fbbeb33f48379e056a48c077ac04a59c502125d9 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Sat, 8 Jan 2022 17:17:32 -0500 Subject: [PATCH 61/80] Lint --- src/components/emoji_picker/emoji_picker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index bf4a98d4d..07f4b0053 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -43,7 +43,7 @@ const UNICODE_EMOJI_GROUP_ICON = { 'activities': 'basketball-ball', 'objects': 'lightbulb', 'symbols': 'code', - 'flags': 'flag', + 'flags': 'flag' } const filterByKeyword = (list, keyword = '') => { From 96564609f87e93d32448da6c7d6a75cea50eff93 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 17 Jan 2022 23:41:11 -0500 Subject: [PATCH 62/80] Make StillImage react to src changes --- src/components/still-image/still-image.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/components/still-image/still-image.js b/src/components/still-image/still-image.js index 1806d33b0..200ef147d 100644 --- a/src/components/still-image/still-image.js +++ b/src/components/still-image/still-image.js @@ -57,6 +57,14 @@ const StillImage = { onError () { this.imageLoadError && this.imageLoadError() } + }, + watch: { + src () { + this.realSrc = this.src + }, + dataSrc () { + this.$el.removeAttribute('data-loaded') + } } } From e01c76c7e90f354436e726456532f51288a7ab99 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Wed, 6 Apr 2022 21:29:50 -0400 Subject: [PATCH 63/80] Make emoji picker work with vue3 --- src/components/emoji_picker/emoji_picker.js | 21 ++++++++++++++------ src/components/emoji_picker/emoji_picker.vue | 8 +++++--- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 07f4b0053..677ef5e47 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -84,7 +84,9 @@ const EmojiPicker = { keepOpen: false, customEmojiTimeout: null, // Lazy-load only after the first time `showing` becomes true. - contentLoaded: false + contentLoaded: false, + groupRefs: {}, + emojiRefs: {} } }, components: { @@ -93,6 +95,12 @@ const EmojiPicker = { StillImage }, methods: { + setGroupRef (name) { + return el => { this.groupRefs[name] = el } + }, + setEmojiRef (name) { + return el => { this.emojiRefs[name] = el } + }, onStickerUploaded (e) { this.$emit('sticker-uploaded', e) }, @@ -112,8 +120,8 @@ const EmojiPicker = { const top = target.scrollTop + 5 this.$nextTick(() => { this.allEmojiGroups.forEach(group => { - const ref = this.$refs['group-' + group.id] - if (ref[0].offsetTop <= top) { + const ref = this.groupRefs['group-' + group.id] + if (ref && ref.offsetTop <= top) { this.activeGroup = group.id } }) @@ -122,7 +130,7 @@ const EmojiPicker = { }, scrollHeader () { // Scroll the active tab's header into view - const headerRef = this.$refs['group-header-' + this.activeGroup][0] + const headerRef = this.groupRefs['group-header-' + this.activeGroup] const left = headerRef.offsetLeft const right = left + headerRef.offsetWidth const headerCont = this.$refs.header @@ -138,7 +146,7 @@ const EmojiPicker = { } }, highlight (key) { - const ref = this.$refs['group-' + key] + const ref = this.groupRefs['group-' + key] const top = ref.offsetTop this.setShowStickers(false) this.activeGroup = key @@ -169,7 +177,8 @@ const EmojiPicker = { this.$nextTick(() => { this.$lozad = lozad('.still-image.emoji-picker-emoji', { load: el => { - const vn = el.__vue__ + const name = el.getAttribute('data-emoji-name') + const vn = this.emojiRefs[name] if (!vn) { return } diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index e8d42c243..a6a634110 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -9,7 +9,7 @@ > {{ group.text }} @@ -96,10 +96,12 @@
- + From 0fd0d6c4c2c7791f889135727f8afef10a36472d Mon Sep 17 00:00:00 2001 From: Tusooa ZhuDate: Fri, 29 Apr 2022 22:40:06 -0400 Subject: [PATCH 64/80] Limit the width of unsupported multichar emojis --- src/components/emoji_picker/emoji_picker.scss | 8 ++++++-- src/components/emoji_picker/emoji_picker.vue | 7 +++++-- 2 files changed, 11 insertions(+), 4 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss index 222749d01..af01b3ec0 100644 --- a/src/components/emoji_picker/emoji_picker.scss +++ b/src/components/emoji_picker/emoji_picker.scss @@ -198,18 +198,22 @@ $emoji-picker-emoji-size: 32px; height: $emoji-picker-emoji-size; box-sizing: border-box; display: flex; - font-size: $emoji-picker-emoji-size; + line-height: $emoji-picker-emoji-size; align-items: center; justify-content: center; margin: 4px; cursor: pointer; - img { + .emoji-picker-emoji.-custom { object-fit: contain; max-width: 100%; max-height: 100%; } + .emoji-picker-emoji.-unicode { + font-size: 24px; + overflow: hidden; + } } } diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index a6a634110..e5a5958ce 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -92,10 +92,13 @@ class="emoji-item" @click.stop.prevent="onEmoji(emoji)" > - {{ emoji.replacement }} + {{ emoji.replacement }} Date: Mon, 20 Jun 2022 08:50:32 -0400 Subject: [PATCH 65/80] Use trimmed keyword for filtering emojis --- src/components/emoji_picker/emoji_picker.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 677ef5e47..3cb6f76d2 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -270,7 +270,7 @@ const EmojiPicker = { return this.allEmojiGroups .map(group => ({ ...group, - emojis: filterByKeyword(group.emojis, this.keyword) + emojis: filterByKeyword(group.emojis, trim(this.keyword)) })) .filter(group => group.emojis.length > 0) }, From 5d6f3a5c8bd3acc53e51b4300c93051ddc1b627b Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Thu, 7 Jul 2022 23:10:06 -0400 Subject: [PATCH 66/80] Tweak efficiency when changing filter keywords in emoji picker --- src/components/emoji_picker/emoji_picker.js | 31 +++++++++++++-------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 3cb6f76d2..6a7b52853 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -17,7 +17,7 @@ import { faCode, faFlag } from '@fortawesome/free-solid-svg-icons' -import { trim } from 'lodash' +import { debounce, trim } from 'lodash' library.add( faBoxOpen, @@ -86,7 +86,8 @@ const EmojiPicker = { // Lazy-load only after the first time `showing` becomes true. contentLoaded: false, groupRefs: {}, - emojiRefs: {} + emojiRefs: {}, + filteredEmojiGroups: [] } }, components: { @@ -206,6 +207,7 @@ const EmojiPicker = { const oldContentLoaded = this.contentLoaded this.contentLoaded = true this.waitForDomAndInitializeLazyLoad() + this.filteredEmojiGroups = this.getFilteredEmojiGroups() if (!oldContentLoaded) { this.$nextTick(() => { if (this.defaultGroup) { @@ -213,15 +215,24 @@ const EmojiPicker = { } }) } + }, + getFilteredEmojiGroups () { + return this.allEmojiGroups + .map(group => ({ + ...group, + emojis: filterByKeyword(group.emojis, trim(this.keyword)) + })) + .filter(group => group.emojis.length > 0) } }, watch: { keyword () { this.onScroll() - this.waitForDomAndInitializeLazyLoad() + this.debouncedHandleKeywordChange() }, allCustomGroups () { this.waitForDomAndInitializeLazyLoad() + this.filteredEmojiGroups = this.getFilteredEmojiGroups() }, showing (val) { if (val) { @@ -266,16 +277,14 @@ const EmojiPicker = { .map(([_, v]) => v) .concat(this.unicodeEmojiGroups) }, - filteredEmojiGroups () { - return this.allEmojiGroups - .map(group => ({ - ...group, - emojis: filterByKeyword(group.emojis, trim(this.keyword)) - })) - .filter(group => group.emojis.length > 0) - }, stickerPickerEnabled () { return (this.$store.state.instance.stickers || []).length !== 0 + }, + debouncedHandleKeywordChange () { + return debounce(() => { + this.waitForDomAndInitializeLazyLoad() + this.filteredEmojiGroups = this.getFilteredEmojiGroups() + }, 500) } } } From 58b01db9e1f466607b810b1900db1d8e4411ccad Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 1 Aug 2022 11:03:52 -0400 Subject: [PATCH 67/80] Fix emoji picker lint --- src/components/emoji_picker/emoji_picker.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 6a7b52853..c2ae76f34 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -40,10 +40,10 @@ const UNICODE_EMOJI_GROUP_ICON = { 'animals-and-nature': 'paw', 'food-and-drink': 'ice-cream', 'travel-and-places': 'bus', - 'activities': 'basketball-ball', - 'objects': 'lightbulb', - 'symbols': 'code', - 'flags': 'flag' + activities: 'basketball-ball', + objects: 'lightbulb', + symbols: 'code', + flags: 'flag' } const filterByKeyword = (list, keyword = '') => { From 6e2b87f5af922d27ee87b9fec64c5308832a41af Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Mon, 1 Aug 2022 11:30:54 -0400 Subject: [PATCH 68/80] Fix emoji picker lint --- src/components/emoji_picker/emoji_picker.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index e5a5958ce..689138e6d 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -98,8 +98,8 @@ >{{ emoji.replacement }} From 8bd27165f38e8568950992bc82058da676e56f18 Mon Sep 17 00:00:00 2001 From: HJ <30-hj@users.noreply.git.pleroma.social> Date: Thu, 18 Aug 2022 13:10:24 +0000 Subject: [PATCH 69/80] Fix non-square emojis being truncated --- src/components/emoji_picker/emoji_picker.scss | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/components/emoji_picker/emoji_picker.scss b/src/components/emoji_picker/emoji_picker.scss index af01b3ec0..016c46d78 100644 --- a/src/components/emoji_picker/emoji_picker.scss +++ b/src/components/emoji_picker/emoji_picker.scss @@ -35,6 +35,8 @@ $emoji-picker-emoji-size: 32px; .still-image { max-width: 100%; max-height: 100%; + height: 100%; + width: 100%; object-fit: contain; } } From de2c7b760fd5a16a3f580c85ac3beb493a6ad0c3 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Fri, 19 Aug 2022 08:46:53 -0400 Subject: [PATCH 70/80] Use console.info --- build/update-emoji.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build/update-emoji.js b/build/update-emoji.js index 5336a95bd..fba7706ef 100644 --- a/build/update-emoji.js +++ b/build/update-emoji.js @@ -20,8 +20,8 @@ module.exports = { res[groupId] = emojis[k] }) - console.log('Updating emojis...') + console.info('Updating emojis...') fs.writeFileSync('static/emoji.json', JSON.stringify(res)) - console.log('Done.') + console.info('Done.') } } From 0445d7c882a5b1d213b0ff5e54e91d6225101c66 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Wed, 31 Aug 2022 16:03:15 -0400 Subject: [PATCH 71/80] Make unicode emoji phrases match with _ --- src/modules/instance.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/instance.js b/src/modules/instance.js index 2fcb059c5..9df01bfdf 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -190,7 +190,7 @@ const instance = { const values = await res.json() const emoji = Object.keys(values).reduce((res, groupId) => { res[groupId] = values[groupId].map(e => ({ - displayText: e.name, + displayText: e.slug, imageUrl: false, replacement: e.emoji })) From fa1d9f3fb4a886cde2553739f5f9a83aa35f2fdd Mon Sep 17 00:00:00 2001 From: Henry Jameson Date: Tue, 20 Sep 2022 00:24:08 +0300 Subject: [PATCH 72/80] using the half-shit approach since proper approach is full-shit --- .../update_notification/update_notification.js | 15 +++++---------- .../update_notification/update_notification.scss | 12 +++++++++--- .../update_notification/update_notification.vue | 7 +++++-- 3 files changed, 19 insertions(+), 15 deletions(-) diff --git a/src/components/update_notification/update_notification.js b/src/components/update_notification/update_notification.js index 06241688f..ddf379f5c 100644 --- a/src/components/update_notification/update_notification.js +++ b/src/components/update_notification/update_notification.js @@ -17,9 +17,9 @@ export const CURRENT_UPDATE_COUNTER = 1 const UpdateNotification = { data () { return { + showingImage: false, pleromaTanVariant: Math.random() > 0.5 ? pleromaTan : pleromaTanFox, - showingMore: false, - contentHeight: 0 + showingMore: false } }, components: { @@ -32,11 +32,6 @@ const UpdateNotification = { 'shape-outside': 'url(' + mask + ')' } }, - dynamicStyles () { - return { - '--____extraInfoGroupHeight': this.contentHeight + 'px' - } - }, shouldShow () { return !this.$store.state.instance.disableUpdateNotification && this.$store.state.users.currentUser && @@ -60,12 +55,12 @@ const UpdateNotification = { } }, mounted () { + this.contentHeightNoImage = this.$refs.animatedText.scrollHeight + // Workaround to get the text height only after mask loaded. A bit hacky. const newImg = new Image() newImg.onload = () => { - setTimeout(() => { - this.contentHeight = this.$refs.animatedText.scrollHeight - }, 100) + setTimeout(() => { this.showingImage = true }, 100) } newImg.src = this.pleromaTanVariant === pleromaTan ? pleromaTanMask : pleromaTanFoxMask } diff --git a/src/components/update_notification/update_notification.scss b/src/components/update_notification/update_notification.scss index 8cad1bc73..ce8129d0f 100644 --- a/src/components/update_notification/update_notification.scss +++ b/src/components/update_notification/update_notification.scss @@ -35,6 +35,12 @@ margin-top: calc(-1 * var(--__top-fringe)); margin-bottom: calc(-1 * var(--__bottom-fringe)); margin-right: calc(-1 * var(--__right-fringe)); + + &.-noImage { + .text { + padding-right: var(--__right-fringe); + } + } } .panel-body { @@ -75,9 +81,9 @@ .extra-info-group { transition: max-height, padding, height; - transition-timing-function: ease-in-out; - transition-duration: 500ms; - max-height: calc(var(--____extraInfoGroupHeight) + 1em); // include bottom padding + transition-timing-function: ease-in; + transition-duration: 700ms; + max-height: 70vh; mask: linear-gradient(to top, white, transparent) bottom/100% 2px no-repeat, linear-gradient(to top, white, white); diff --git a/src/components/update_notification/update_notification.vue b/src/components/update_notification/update_notification.vue index 00841af22..78e70a743 100644 --- a/src/components/update_notification/update_notification.vue +++ b/src/components/update_notification/update_notification.vue @@ -7,7 +7,6 @@ @@ -15,8 +14,12 @@-+diff --git a/src/components/emoji_input/suggestor.js b/src/components/emoji_input/suggestor.js index 1765f8438..adaa879e3 100644 --- a/src/components/emoji_input/suggestor.js +++ b/src/components/emoji_input/suggestor.js @@ -13,10 +13,10 @@ export default data => { const emojiCurry = suggestEmoji(data.emoji) const usersCurry = data.store && suggestUsers(data.store) - return input => { + return (input, nameKeywordLocalizer) => { const firstChar = input[0] if (firstChar === ':' && data.emoji) { - return emojiCurry(input) + return emojiCurry(input, nameKeywordLocalizer) } if (firstChar === '@' && usersCurry) { return usersCurry(input) @@ -25,34 +25,34 @@ export default data => { } } -export const suggestEmoji = emojis => input => { +export const suggestEmoji = emojis => (input, nameKeywordLocalizer) => { const noPrefix = input.toLowerCase().substr(1) return emojis - .filter(({ displayText }) => displayText.toLowerCase().match(noPrefix)) - .sort((a, b) => { - let aScore = 0 - let bScore = 0 + .map(emoji => ({ ...emoji, ...nameKeywordLocalizer(emoji) })) + .filter((emoji) => (emoji.names.concat(emoji.keywords)).filter(kw => kw.toLowerCase().match(noPrefix)).length) + .map(k => { + let score = 0 // An exact match always wins - aScore += a.displayText.toLowerCase() === noPrefix ? 200 : 0 - bScore += b.displayText.toLowerCase() === noPrefix ? 200 : 0 + score += Math.max(...k.names.map(name => name.toLowerCase() === noPrefix ? 200 : 0), 0) // Prioritize custom emoji a lot - aScore += a.imageUrl ? 100 : 0 - bScore += b.imageUrl ? 100 : 0 + score += k.imageUrl ? 100 : 0 // Prioritize prefix matches somewhat - aScore += a.displayText.toLowerCase().startsWith(noPrefix) ? 10 : 0 - bScore += b.displayText.toLowerCase().startsWith(noPrefix) ? 10 : 0 + score += Math.max(...k.names.map(kw => kw.toLowerCase().startsWith(noPrefix) ? 10 : 0), 0) // Sort by length - aScore -= a.displayText.length - bScore -= b.displayText.length + score -= k.displayText.length + k.score = score + return k + }) + .sort((a, b) => { // Break ties alphabetically const alphabetically = a.displayText > b.displayText ? 0.5 : -0.5 - return bScore - aScore + alphabetically + return b.score - a.score + alphabetically }) }Date: Tue, 20 Sep 2022 19:27:26 -0400 Subject: [PATCH 73/80] Extract language list to its own file --- package.json | 5 +++-- src/i18n/languages.js | 44 ++++++++++++++++++++++++++++++++++++++++++ src/i18n/messages.js | 45 ++++++++++++------------------------------- yarn.lock | 5 +++++ 4 files changed, 64 insertions(+), 35 deletions(-) create mode 100644 src/i18n/languages.js diff --git a/package.json b/package.json index 5a2407c61..b0c06a61a 100644 --- a/package.json +++ b/package.json @@ -23,6 +23,7 @@ "@fortawesome/free-solid-svg-icons": "6.2.0", "@fortawesome/vue-fontawesome": "3.0.1", "@kazvmoe-infra/pinch-zoom-element": "1.2.0", + "@kazvmoe-infra/unicode-emoji-json": "^0.4.0", "@ruffle-rs/ruffle": "0.1.0-nightly.2022.7.12", "@vuelidate/core": "2.0.0-alpha.44", "@vuelidate/validators": "2.0.0-alpha.31", @@ -34,8 +35,8 @@ "escape-html": "1.0.3", "js-cookie": "3.0.1", "localforage": "1.10.0", - "parse-link-header": "2.0.0", "lozad": "^1.16.0", + "parse-link-header": "2.0.0", "phoenix": "1.6.2", "punycode.js": "2.1.0", "qrcode": "1.5.0", @@ -116,8 +117,8 @@ "stylelint": "13.13.1", "stylelint-config-standard": "20.0.0", "stylelint-rscss": "0.4.0", - "vue-loader": "17.0.0", "unicode-emoji-json": "^0.3.0", + "vue-loader": "17.0.0", "vue-style-loader": "4.1.3", "webpack": "5.74.0", "webpack-dev-middleware": "3.7.3", diff --git a/src/i18n/languages.js b/src/i18n/languages.js new file mode 100644 index 000000000..b1cb1d7eb --- /dev/null +++ b/src/i18n/languages.js @@ -0,0 +1,44 @@ + +const languages = [ + 'ar', + 'ca', + 'cs', + 'de', + 'eo', + 'en', + 'es', + 'et', + 'eu', + 'fi', + 'fr', + 'ga', + 'he', + 'hu', + 'it', + 'ja', + 'ja_easy', + 'ko', + 'nb', + 'nl', + 'oc', + 'pl', + 'pt', + 'ro', + 'ru', + 'sk', + 'te', + 'uk', + 'zh', + 'zh_Hant' +] + +const specialJsonName = { + ja: 'ja_pedantic' +} + +const langCodeToJsonName = (code) => specialJsonName[code] || code + +module.exports = { + languages, + langCodeToJsonName +} diff --git a/src/i18n/messages.js b/src/i18n/messages.js index eae75c80e..8cf259734 100644 --- a/src/i18n/messages.js +++ b/src/i18n/messages.js @@ -7,46 +7,25 @@ // sed -i -e "s/'//gm" -e 's/"/\\"/gm' -re 's/^( +)(.+?): ((.+?))?(,?)(\{?)$/\1"\2": "\4"/gm' -e 's/\"\{\"/{/g' -e 's/,"$/",/g' file.json // There's only problem that apostrophe character ' gets replaced by \\ so you have to fix it manually, sorry. -const loaders = { - ar: () => import('./ar.json'), - ca: () => import('./ca.json'), - cs: () => import('./cs.json'), - de: () => import('./de.json'), - eo: () => import('./eo.json'), - es: () => import('./es.json'), - et: () => import('./et.json'), - eu: () => import('./eu.json'), - fi: () => import('./fi.json'), - fr: () => import('./fr.json'), - ga: () => import('./ga.json'), - he: () => import('./he.json'), - hu: () => import('./hu.json'), - it: () => import('./it.json'), - ja: () => import('./ja_pedantic.json'), - ja_easy: () => import('./ja_easy.json'), - ko: () => import('./ko.json'), - nb: () => import('./nb.json'), - nl: () => import('./nl.json'), - oc: () => import('./oc.json'), - pl: () => import('./pl.json'), - pt: () => import('./pt.json'), - ro: () => import('./ro.json'), - ru: () => import('./ru.json'), - sk: () => import('./sk.json'), - te: () => import('./te.json'), - uk: () => import('./uk.json'), - zh: () => import('./zh.json'), - zh_Hant: () => import('./zh_Hant.json') +import { languages, langCodeToJsonName } from './languages.js' + +const hasLanguageFile = (code) => languages.includes(code) + +const loadLanguageFile = (code) => { + return import( + /* webpackInclude: /\.json$/ */ + `./${langCodeToJsonName(code)}.json` + ) } const messages = { - languages: ['en', ...Object.keys(loaders)], + languages, default: { en: require('./en.json').default }, setLanguage: async (i18n, language) => { - if (loaders[language]) { - const messages = await loaders[language]() + if (hasLanguageFile(language)) { + const messages = await loadLanguageFile(language) i18n.setLocaleMessage(language, messages.default) } i18n.locale = language diff --git a/yarn.lock b/yarn.lock index a971bf9ae..f1cfc7f3b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1629,6 +1629,11 @@ dependencies: pointer-tracker "^2.0.3" +"@kazvmoe-infra/unicode-emoji-json@^0.4.0": + version "0.4.0" + resolved "https://registry.yarnpkg.com/@kazvmoe-infra/unicode-emoji-json/-/unicode-emoji-json-0.4.0.tgz#555bab2f8d11db74820ef0a2fbe2805b17c22587" + integrity sha512-22OffREdHzD0U6A/W4RaFPV8NR73za6euibtAxNxO/fu5A6TwxRO2lAdbDWKJH9COv/vYs8zqfEiSalXH2nXJA== + "@nightwatch/chai@5.0.2": version "5.0.2" resolved "https://registry.yarnpkg.com/@nightwatch/chai/-/chai-5.0.2.tgz#86b20908fc090dffd5c9567c0392bc6a494cc2e6" From 1c3bdda14c0edf4ce321745bcf43e395635d6bf1 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu
Date: Tue, 20 Sep 2022 20:15:32 -0400 Subject: [PATCH 74/80] Load unicode emoji annotations --- src/i18n/languages.js | 10 +++++++++- src/modules/config.js | 1 + src/modules/instance.js | 24 ++++++++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/src/i18n/languages.js b/src/i18n/languages.js index b1cb1d7eb..40cf04f2e 100644 --- a/src/i18n/languages.js +++ b/src/i18n/languages.js @@ -38,7 +38,15 @@ const specialJsonName = { const langCodeToJsonName = (code) => specialJsonName[code] || code +const langCodeToCldrName = (code) => code + +const ensureFinalFallback = codes => { + return codes.includes('en') ? codes : codes.concat(['en']) +} + module.exports = { languages, - langCodeToJsonName + langCodeToJsonName, + langCodeToCldrName, + ensureFinalFallback } diff --git a/src/modules/config.js b/src/modules/config.js index eeaac917c..c966602ec 100644 --- a/src/modules/config.js +++ b/src/modules/config.js @@ -183,6 +183,7 @@ const config = { break case 'interfaceLanguage': messages.setLanguage(this.getters.i18n, value) + dispatch('loadUnicodeEmojiData', value) Cookies.set(BACKEND_LANGUAGE_COOKIE_NAME, localeService.internalToBackendLocale(value)) break case 'thirdColumnMode': diff --git a/src/modules/instance.js b/src/modules/instance.js index 9df01bfdf..c0c7cef0a 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -2,6 +2,7 @@ import { getPreset, applyTheme } from '../services/style_setter/style_setter.js' import { CURRENT_VERSION } from '../services/theme_data/theme_data.service.js' import apiService from '../services/api/api.service.js' import { instanceDefaultProperties } from './config.js' +import { langCodeToCldrName, ensureFinalFallback } from '../i18n/languages.js' const SORTED_EMOJI_GROUP_IDS = [ 'smileys-and-emotion', @@ -78,6 +79,7 @@ const defaultState = { customEmojiFetched: false, emoji: {}, emojiFetched: false, + unicodeEmojiAnnotations: {}, pleromaBackend: true, postFormats: [], restrictedNicknames: [], @@ -109,6 +111,12 @@ const defaultState = { } } +const loadAnnotations = (lang) => { + return import( + `@kazvmoe-infra/unicode-emoji-json/annotations/${langCodeToCldrName(lang)}.json` + ) +} + const instance = { state: defaultState, mutations: { @@ -119,6 +127,9 @@ const instance = { }, setKnownDomains (state, domains) { state.knownDomains = domains + }, + setUnicodeEmojiAnnotations (state, { lang, annotations }) { + state.unicodeEmojiAnnotations[lang] = annotations } }, getters: { @@ -206,6 +217,19 @@ const instance = { } }, + loadUnicodeEmojiData ({ commit, state }, language) { + const langList = ensureFinalFallback(Array.isArray(language) ? language : [language]) + + return Promise.all( + langList + .forEach(async lang => { + if (!state.unicodeEmojiAnnotations[lang]) { + const annotations = await loadAnnotations(lang) + commit('setUnicodeEmojiAnnotations', { lang, annotations }) + } + })) + }, + async getCustomEmoji ({ commit, state }) { try { const res = await window.fetch('/api/pleroma/emoji.json') From a73f9731f5ad78d1e6f1bd211ad2971d21fc1379 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Tue, 20 Sep 2022 20:44:52 -0400 Subject: [PATCH 75/80] Display localized unicode emoji names --- src/components/emoji_picker/emoji_picker.js | 20 ++++++++++++++++++++ src/components/emoji_picker/emoji_picker.vue | 2 +- src/i18n/languages.js | 3 ++- src/modules/instance.js | 18 +++++++++++++++--- 4 files changed, 38 insertions(+), 5 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index c2ae76f34..2ebead53e 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -1,6 +1,7 @@ import { defineAsyncComponent } from 'vue' import Checkbox from '../checkbox/checkbox.vue' import StillImage from '../still-image/still-image.vue' +import { ensureFinalFallback } from '../../i18n/languages.js' import lozad from 'lozad' import { library } from '@fortawesome/fontawesome-svg-core' import { @@ -285,6 +286,25 @@ const EmojiPicker = { this.waitForDomAndInitializeLazyLoad() this.filteredEmojiGroups = this.getFilteredEmojiGroups() }, 500) + }, + languages () { + console.log('languages:', ensureFinalFallback(this.$store.getters.mergedConfig.interfaceLanguage)) + return ensureFinalFallback(this.$store.getters.mergedConfig.interfaceLanguage) + }, + maybeLocalizedEmojiName () { + return emoji => { + if (!emoji.annotations) { + return emoji.displayText + } + + for (const lang of this.languages) { + if (emoji.annotations[lang]?.name) { + return emoji.annotations[lang].name + } + } + + return emoji.displayText + } } } } diff --git a/src/components/emoji_picker/emoji_picker.vue b/src/components/emoji_picker/emoji_picker.vue index 689138e6d..57bb00371 100644 --- a/src/components/emoji_picker/emoji_picker.vue +++ b/src/components/emoji_picker/emoji_picker.vue @@ -88,7 +88,7 @@ diff --git a/src/i18n/languages.js b/src/i18n/languages.js index 40cf04f2e..250b3b1a9 100644 --- a/src/i18n/languages.js +++ b/src/i18n/languages.js @@ -41,7 +41,8 @@ const langCodeToJsonName = (code) => specialJsonName[code] || code const langCodeToCldrName = (code) => code const ensureFinalFallback = codes => { - return codes.includes('en') ? codes : codes.concat(['en']) + const codeList = Array.isArray(codes) ? codes : [codes] + return codeList.includes('en') ? codeList : codeList.concat(['en']) } module.exports = { diff --git a/src/modules/instance.js b/src/modules/instance.js index c0c7cef0a..5a72a6d3e 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -117,6 +117,18 @@ const loadAnnotations = (lang) => { ) } +const injectAnnotations = (emoji, annotations) => { + const availableLangs = Object.keys(annotations) + + return { + ...emoji, + annotations: availableLangs.reduce((acc, cur) => { + acc[cur] = annotations[cur][emoji.replacement] + return acc + }, {}) + } +} + const instance = { state: defaultState, mutations: { @@ -164,13 +176,13 @@ const instance = { }, standardEmojiList (state) { return SORTED_EMOJI_GROUP_IDS - .map(groupId => state.emoji[groupId] || []) + .map(groupId => (state.emoji[groupId] || []).map(k => injectAnnotations(k, state.unicodeEmojiAnnotations))) .reduce((a, b) => a.concat(b), []) }, standardEmojiGroupList (state) { return SORTED_EMOJI_GROUP_IDS.map(groupId => ({ id: groupId, - emojis: state.emoji[groupId] || [] + emojis: (state.emoji[groupId] || []).map(k => injectAnnotations(k, state.unicodeEmojiAnnotations)) })) }, instanceDomain (state) { @@ -218,7 +230,7 @@ const instance = { }, loadUnicodeEmojiData ({ commit, state }, language) { - const langList = ensureFinalFallback(Array.isArray(language) ? language : [language]) + const langList = ensureFinalFallback(language) return Promise.all( langList From 980241c1ac4044e66a4f702d5420affc4a3bb9a0 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Tue, 20 Sep 2022 21:06:57 -0400 Subject: [PATCH 76/80] Support filtering by keywords from cldr --- src/components/emoji_picker/emoji_picker.js | 25 +++++++++++++++++---- 1 file changed, 21 insertions(+), 4 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index 2ebead53e..bf5e0e439 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -47,13 +47,30 @@ const UNICODE_EMOJI_GROUP_ICON = { flags: 'flag' } -const filterByKeyword = (list, keyword = '') => { +const maybeLocalizedKeywords = (emoji, languages) => { + const res = [emoji.displayText] + if (emoji.annotations) { + languages.forEach(lang => { + const keywords = emoji.annotations[lang]?.keywords || [] + const name = emoji.annotations[lang]?.name + res.push(...(keywords.concat([name]).filter(k => k))) + }) + } + return res +} + +const filterByKeyword = (list, keyword = '', languages) => { if (keyword === '') return list const keywordLowercase = keyword.toLowerCase() const orderedEmojiList = [] for (const emoji of list) { - const indexOfKeyword = emoji.displayText.toLowerCase().indexOf(keywordLowercase) + const indices = maybeLocalizedKeywords(emoji, languages) + .map(k => k.toLowerCase().indexOf(keywordLowercase)) + .filter(k => k > -1) + + const indexOfKeyword = indices.length ? Math.min(...indices) : -1 + if (indexOfKeyword > -1) { if (!Array.isArray(orderedEmojiList[indexOfKeyword])) { orderedEmojiList[indexOfKeyword] = [] @@ -172,7 +189,7 @@ const EmojiPicker = { this.showingStickers = value }, filterByKeyword (list, keyword) { - return filterByKeyword(list, keyword) + return filterByKeyword(list, keyword, this.languages) }, initializeLazyLoad () { this.destroyLazyLoad() @@ -221,7 +238,7 @@ const EmojiPicker = { return this.allEmojiGroups .map(group => ({ ...group, - emojis: filterByKeyword(group.emojis, trim(this.keyword)) + emojis: this.filterByKeyword(group.emojis, trim(this.keyword)) })) .filter(group => group.emojis.length > 0) } From cc58b9b93d4346860e244d2093f0d406eb76954c Mon Sep 17 00:00:00 2001 From: Tusooa Zhu {{ suggestion.detailText }}Date: Tue, 20 Sep 2022 21:50:40 -0400 Subject: [PATCH 77/80] Add regional indicators --- src/components/emoji_picker/emoji_picker.js | 15 ++++++----- src/i18n/en.json | 3 ++- src/modules/instance.js | 29 +++++++++++++++++++-- 3 files changed, 38 insertions(+), 9 deletions(-) diff --git a/src/components/emoji_picker/emoji_picker.js b/src/components/emoji_picker/emoji_picker.js index bf5e0e439..fafc2af18 100644 --- a/src/components/emoji_picker/emoji_picker.js +++ b/src/components/emoji_picker/emoji_picker.js @@ -47,8 +47,8 @@ const UNICODE_EMOJI_GROUP_ICON = { flags: 'flag' } -const maybeLocalizedKeywords = (emoji, languages) => { - const res = [emoji.displayText] +const maybeLocalizedKeywords = (emoji, languages, nameLocalizer) => { + const res = [emoji.displayText, nameLocalizer(emoji)] if (emoji.annotations) { languages.forEach(lang => { const keywords = emoji.annotations[lang]?.keywords || [] @@ -59,13 +59,13 @@ const maybeLocalizedKeywords = (emoji, languages) => { return res } -const filterByKeyword = (list, keyword = '', languages) => { +const filterByKeyword = (list, keyword = '', languages, nameLocalizer) => { if (keyword === '') return list const keywordLowercase = keyword.toLowerCase() const orderedEmojiList = [] for (const emoji of list) { - const indices = maybeLocalizedKeywords(emoji, languages) + const indices = maybeLocalizedKeywords(emoji, languages, nameLocalizer) .map(k => k.toLowerCase().indexOf(keywordLowercase)) .filter(k => k > -1) @@ -189,7 +189,7 @@ const EmojiPicker = { this.showingStickers = value }, filterByKeyword (list, keyword) { - return filterByKeyword(list, keyword, this.languages) + return filterByKeyword(list, keyword, this.languages, this.maybeLocalizedEmojiName) }, initializeLazyLoad () { this.destroyLazyLoad() @@ -305,7 +305,6 @@ const EmojiPicker = { }, 500) }, languages () { - console.log('languages:', ensureFinalFallback(this.$store.getters.mergedConfig.interfaceLanguage)) return ensureFinalFallback(this.$store.getters.mergedConfig.interfaceLanguage) }, maybeLocalizedEmojiName () { @@ -314,6 +313,10 @@ const EmojiPicker = { return emoji.displayText } + if (emoji.displayTextI18n) { + return this.$t(emoji.displayTextI18n.key, emoji.displayTextI18n.args) + } + for (const lang of this.languages) { if (emoji.annotations[lang]?.name) { return emoji.annotations[lang].name diff --git a/src/i18n/en.json b/src/i18n/en.json index 2a665bd59..fb941c8dd 100644 --- a/src/i18n/en.json +++ b/src/i18n/en.json @@ -211,7 +211,8 @@ "travel-and-places": "Travel & Places" }, "load_all_hint": "Loaded first {saneAmount} emoji, loading all emoji may cause performance issues.", - "load_all": "Loading all {emojiAmount} emoji" + "load_all": "Loading all {emojiAmount} emoji", + "regional_indicator": "Regional indicator {letter}" }, "errors": { "storage_unavailable": "Pleroma could not access browser storage. Your login or your local settings won't be saved and you might encounter unexpected issues. Try enabling cookies." diff --git a/src/modules/instance.js b/src/modules/instance.js index 5a72a6d3e..9be35d887 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -16,6 +16,26 @@ const SORTED_EMOJI_GROUP_IDS = [ 'flags' ] +const REGIONAL_INDICATORS = (() => { + const start = 0x1F1E6 + const end = 0x1F1FF + const A = 'A'.codePointAt(0) + const res = new Array(end - start + 1) + for (let i = start; i <= end; ++i) { + const letter = String.fromCodePoint(A + i - start) + res[i - start] = { + replacement: String.fromCodePoint(i), + imageUrl: false, + displayText: 'regional_indicator_' + letter, + displayTextI18n: { + key: 'emoji.regional_indicator', + args: { letter } + } + } + } + return res +})() + const defaultState = { // Stuff from apiConfig name: 'Pleroma FE', @@ -129,6 +149,11 @@ const injectAnnotations = (emoji, annotations) => { } } +const injectRegionalIndicators = groups => { + groups.symbols.push(...REGIONAL_INDICATORS) + return groups +} + const instance = { state: defaultState, mutations: { @@ -219,7 +244,7 @@ const instance = { })) return res }, {}) - commit('setInstanceOption', { name: 'emoji', value: emoji }) + commit('setInstanceOption', { name: 'emoji', value: injectRegionalIndicators(emoji) }) } else { throw (res) } @@ -234,7 +259,7 @@ const instance = { return Promise.all( langList - .forEach(async lang => { + .map(async lang => { if (!state.unicodeEmojiAnnotations[lang]) { const annotations = await loadAnnotations(lang) commit('setUnicodeEmojiAnnotations', { lang, annotations }) From 6fab7b9e3ffb4a9bce2788174ef0e9e6eef7b2c5 Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Tue, 20 Sep 2022 22:03:31 -0400 Subject: [PATCH 78/80] Use import() for emoji.json --- build/update-emoji.js | 2 +- package.json | 1 - src/modules/instance.js | 27 ++++++++++++--------------- yarn.lock | 5 ----- 4 files changed, 13 insertions(+), 22 deletions(-) diff --git a/build/update-emoji.js b/build/update-emoji.js index fba7706ef..9f4b4e67a 100644 --- a/build/update-emoji.js +++ b/build/update-emoji.js @@ -1,7 +1,7 @@ module.exports = { updateEmoji () { - const emojis = require('unicode-emoji-json/data-by-group') + const emojis = require('@kazvmoe-infra/unicode-emoji-json/data-by-group') const fs = require('fs') Object.keys(emojis) diff --git a/package.json b/package.json index b0c06a61a..260df5730 100644 --- a/package.json +++ b/package.json @@ -117,7 +117,6 @@ "stylelint": "13.13.1", "stylelint-config-standard": "20.0.0", "stylelint-rscss": "0.4.0", - "unicode-emoji-json": "^0.3.0", "vue-loader": "17.0.0", "vue-style-loader": "4.1.3", "webpack": "5.74.0", diff --git a/src/modules/instance.js b/src/modules/instance.js index 9be35d887..9f326d26d 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -135,6 +135,7 @@ const loadAnnotations = (lang) => { return import( `@kazvmoe-infra/unicode-emoji-json/annotations/${langCodeToCldrName(lang)}.json` ) + .then(k => k.default) } const injectAnnotations = (emoji, annotations) => { @@ -233,21 +234,17 @@ const instance = { }, async getStaticEmoji ({ commit }) { try { - const res = await window.fetch('/static/emoji.json') - if (res.ok) { - const values = await res.json() - const emoji = Object.keys(values).reduce((res, groupId) => { - res[groupId] = values[groupId].map(e => ({ - displayText: e.slug, - imageUrl: false, - replacement: e.emoji - })) - return res - }, {}) - commit('setInstanceOption', { name: 'emoji', value: injectRegionalIndicators(emoji) }) - } else { - throw (res) - } + const values = (await import('../../static/emoji.json')).default + + const emoji = Object.keys(values).reduce((res, groupId) => { + res[groupId] = values[groupId].map(e => ({ + displayText: e.slug, + imageUrl: false, + replacement: e.emoji + })) + return res + }, {}) + commit('setInstanceOption', { name: 'emoji', value: injectRegionalIndicators(emoji) }) } catch (e) { console.warn("Can't load static emoji") console.warn(e) diff --git a/yarn.lock b/yarn.lock index f1cfc7f3b..a22ab65dd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -8138,11 +8138,6 @@ unicode-canonical-property-names-ecmascript@^2.0.0: resolved "https://registry.yarnpkg.com/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz#301acdc525631670d39f6146e0e77ff6bbdebddc" integrity sha512-yY5PpDlfVIU5+y/BSCxAJRBIS1Zc2dDG3Ujq+sR0U+JjUevW2JhocOF+soROYDSaAezOzOKuyyixhD6mBknSmQ== -unicode-emoji-json@^0.3.0: - version "0.3.0" - resolved "https://registry.yarnpkg.com/unicode-emoji-json/-/unicode-emoji-json-0.3.0.tgz#965e097ef8a367081c5036f81873015a95a5c1ad" - integrity sha512-yImheILedqhZtVEEenRELu9AnX347ZTA3bVMWAU5WMUv7pdU2hcfpwo2mKN8Rns9uHLmOZP90/4B4SPS5aF/iw== - unicode-match-property-ecmascript@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-2.0.0.tgz#54fd16e0ecb167cf04cf1f756bdcc92eba7976c3" From a758e18dceb4cb11d84d6dff1cdfddb755af60db Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Tue, 20 Sep 2022 23:13:07 -0400 Subject: [PATCH 79/80] Make chunks named --- .babelrc | 2 +- build/webpack.base.conf.js | 3 ++- src/i18n/messages.js | 1 + src/modules/instance.js | 3 ++- 4 files changed, 6 insertions(+), 3 deletions(-) diff --git a/.babelrc b/.babelrc index 373d2c599..4ec104161 100644 --- a/.babelrc +++ b/.babelrc @@ -1,5 +1,5 @@ { "presets": ["@babel/preset-env"], "plugins": ["@babel/plugin-transform-runtime", "lodash", "@vue/babel-plugin-jsx"], - "comments": false + "comments": true } diff --git a/build/webpack.base.conf.js b/build/webpack.base.conf.js index 78b75e3f2..bf9469222 100644 --- a/build/webpack.base.conf.js +++ b/build/webpack.base.conf.js @@ -24,7 +24,8 @@ module.exports = { output: { path: config.build.assetsRoot, publicPath: process.env.NODE_ENV === 'production' ? config.build.assetsPublicPath : config.dev.assetsPublicPath, - filename: '[name].js' + filename: '[name].js', + chunkFilename: '[name].js' }, optimization: { splitChunks: { diff --git a/src/i18n/messages.js b/src/i18n/messages.js index 8cf259734..74a89ca87 100644 --- a/src/i18n/messages.js +++ b/src/i18n/messages.js @@ -14,6 +14,7 @@ const hasLanguageFile = (code) => languages.includes(code) const loadLanguageFile = (code) => { return import( /* webpackInclude: /\.json$/ */ + /* webpackChunkName: "i18n/[request]" */ `./${langCodeToJsonName(code)}.json` ) } diff --git a/src/modules/instance.js b/src/modules/instance.js index 9f326d26d..b1bc9779c 100644 --- a/src/modules/instance.js +++ b/src/modules/instance.js @@ -133,6 +133,7 @@ const defaultState = { const loadAnnotations = (lang) => { return import( + /* webpackChunkName: "emoji-annotations/[request]" */ `@kazvmoe-infra/unicode-emoji-json/annotations/${langCodeToCldrName(lang)}.json` ) .then(k => k.default) @@ -234,7 +235,7 @@ const instance = { }, async getStaticEmoji ({ commit }) { try { - const values = (await import('../../static/emoji.json')).default + const values = (await import(/* webpackChunkName: 'emoji' */ '../../static/emoji.json')).default const emoji = Object.keys(values).reduce((res, groupId) => { res[groupId] = values[groupId].map(e => ({ From a7f836a64e334d6c46ed1e12c7bf9b2ff4a09c7e Mon Sep 17 00:00:00 2001 From: Tusooa Zhu Date: Wed, 21 Sep 2022 23:16:33 -0400 Subject: [PATCH 80/80] Make suggestor suggest according to cldr annotations --- src/components/emoji_input/emoji_input.js | 49 +++++++++++++++++++++- src/components/emoji_input/emoji_input.vue | 2 +- src/components/emoji_input/suggestor.js | 32 +++++++------- 3 files changed, 64 insertions(+), 19 deletions(-) diff --git a/src/components/emoji_input/emoji_input.js b/src/components/emoji_input/emoji_input.js index fb2096c93..ffc0ffac2 100644 --- a/src/components/emoji_input/emoji_input.js +++ b/src/components/emoji_input/emoji_input.js @@ -3,7 +3,7 @@ import EmojiPicker from '../emoji_picker/emoji_picker.vue' import UnicodeDomainIndicator from '../unicode_domain_indicator/unicode_domain_indicator.vue' import { take } from 'lodash' import { findOffset } from '../../services/offset_finder/offset_finder.service.js' - +import { ensureFinalFallback } from '../../i18n/languages.js' import { library } from '@fortawesome/fontawesome-svg-core' import { faSmileBeam @@ -143,6 +143,51 @@ const EmojiInput = { const word = Completion.wordAtPosition(this.modelValue, this.caret - 1) || {} return word } + }, + languages () { + return ensureFinalFallback(this.$store.getters.mergedConfig.interfaceLanguage) + }, + maybeLocalizedEmojiNamesAndKeywords () { + return emoji => { + const names = [emoji.displayText] + const keywords = [] + + if (emoji.displayTextI18n) { + names.push(this.$t(emoji.displayTextI18n.key, emoji.displayTextI18n.args)) + } + + if (emoji.annotations) { + this.languages.forEach(lang => { + names.push(emoji.annotations[lang]?.name) + + keywords.push(...(emoji.annotations[lang]?.keywords || [])) + }) + } + + return { + names: names.filter(k => k), + keywords: keywords.filter(k => k) + } + } + }, + maybeLocalizedEmojiName () { + return emoji => { + if (!emoji.annotations) { + return emoji.displayText + } + + if (emoji.displayTextI18n) { + return this.$t(emoji.displayTextI18n.key, emoji.displayTextI18n.args) + } + + for (const lang of this.languages) { + if (emoji.annotations[lang]?.name) { + return emoji.annotations[lang].name + } + } + + return emoji.displayText + } } }, mounted () { @@ -181,7 +226,7 @@ const EmojiInput = { const firstchar = newWord.charAt(0) this.suggestions = [] if (newWord === firstchar) return - const matchedSuggestions = await this.suggest(newWord) + const matchedSuggestions = await this.suggest(newWord, this.maybeLocalizedEmojiNamesAndKeywords) // Async: cancel if textAtCaret has changed during wait if (this.textAtCaret !== newWord) return if (matchedSuggestions.length <= 0) return diff --git a/src/components/emoji_input/emoji_input.vue b/src/components/emoji_input/emoji_input.vue index eedde9aa2..43581dbf1 100644 --- a/src/components/emoji_input/emoji_input.vue +++ b/src/components/emoji_input/emoji_input.vue @@ -64,7 +64,7 @@ v-if="!suggestion.user" class="displayText" > - {{ suggestion.displayText }} + {{ maybeLocalizedEmojiName(suggestion) }}