From 0e1bda55e856cd97b82ed393b719653872c93e34 Mon Sep 17 00:00:00 2001 From: Ivan Tashkinov Date: Fri, 8 May 2020 21:33:56 +0300 Subject: [PATCH] PleromaFE bundle dropping requirement for embedded account relationships in statuses / notifications. https://git.pleroma.social/pleroma/pleroma-fe/-/commit/7a0e554daf843fe9e98053e79ec0114c380ededb --- priv/static/index.html | 2 +- .../static/font/fontello.1588419330867.woff | Bin 13836 -> 0 bytes .../static/font/fontello.1588419330867.woff2 | Bin 11712 -> 0 bytes ...9330867.eot => fontello.1588947937982.eot} | Bin 22752 -> 22976 bytes ...9330867.svg => fontello.1588947937982.svg} | 2 ++ ...9330867.ttf => fontello.1588947937982.ttf} | Bin 22584 -> 22808 bytes .../static/font/fontello.1588947937982.woff | Bin 0 -> 13988 bytes .../static/font/fontello.1588947937982.woff2 | Bin 0 -> 11816 bytes ...9330867.css => fontello.1588947937982.css} | 14 ++++++++------ priv/static/static/fontello.json | 6 ++++++ ...9fca99e19.js => 2.18e4adec273c4ce867a8.js} | 4 ++-- ...9.js.map => 2.18e4adec273c4ce867a8.js.map} | 2 +- .../static/js/app.996428ccaaaa7f28cb8d.js | 2 ++ .../static/js/app.996428ccaaaa7f28cb8d.js.map | 1 + .../static/js/app.fa89b90e606f4facd209.js | 2 -- .../static/js/app.fa89b90e606f4facd209.js.map | 1 - ...js => vendors~app.561a1c605d1dfb0e6f74.js} | 16 ++++++++-------- .../vendors~app.561a1c605d1dfb0e6f74.js.map | 1 + .../vendors~app.8aa781e6dd81307f544b.js.map | 1 - priv/static/sw-pleroma.js | 2 +- 20 files changed, 33 insertions(+), 23 deletions(-) delete mode 100644 priv/static/static/font/fontello.1588419330867.woff delete mode 100644 priv/static/static/font/fontello.1588419330867.woff2 rename priv/static/static/font/{fontello.1588419330867.eot => fontello.1588947937982.eot} (90%) rename priv/static/static/font/{fontello.1588419330867.svg => fontello.1588947937982.svg} (98%) rename priv/static/static/font/{fontello.1588419330867.ttf => fontello.1588947937982.ttf} (90%) create mode 100644 priv/static/static/font/fontello.1588947937982.woff create mode 100644 priv/static/static/font/fontello.1588947937982.woff2 rename priv/static/static/{fontello.1588419330867.css => fontello.1588947937982.css} (88%) rename priv/static/static/js/{2.1c407059cd79fca99e19.js => 2.18e4adec273c4ce867a8.js} (80%) rename priv/static/static/js/{2.1c407059cd79fca99e19.js.map => 2.18e4adec273c4ce867a8.js.map} (99%) create mode 100644 priv/static/static/js/app.996428ccaaaa7f28cb8d.js create mode 100644 priv/static/static/js/app.996428ccaaaa7f28cb8d.js.map delete mode 100644 priv/static/static/js/app.fa89b90e606f4facd209.js delete mode 100644 priv/static/static/js/app.fa89b90e606f4facd209.js.map rename priv/static/static/js/{vendors~app.8aa781e6dd81307f544b.js => vendors~app.561a1c605d1dfb0e6f74.js} (87%) create mode 100644 priv/static/static/js/vendors~app.561a1c605d1dfb0e6f74.js.map delete mode 100644 priv/static/static/js/vendors~app.8aa781e6dd81307f544b.js.map diff --git a/priv/static/index.html b/priv/static/index.html index 4fac5c100..b37cbaa67 100644 --- a/priv/static/index.html +++ b/priv/static/index.html @@ -1 +1 @@ -Pleroma
\ No newline at end of file +Pleroma
\ No newline at end of file diff --git a/priv/static/static/font/fontello.1588419330867.woff b/priv/static/static/font/fontello.1588419330867.woff deleted file mode 100644 index 2bf4cbc16bfaf89c8e663c3ecdfdea1728fe781d..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 13836 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 diff --git a/priv/static/static/font/fontello.1588419330867.woff2 b/priv/static/static/font/fontello.1588419330867.woff2 deleted file mode 100644 index a31bf3f29df33e61b0472ae87e44d05efe32d05a..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 11712 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 delta 477 zcmZXOF=!KE7>1w!?!4NjVuwN_2#H{;R3{Bhf+7*kscjSosjY%~q-iqr(w|(A=+aSa zOELU7i729?gOc(qICOBdLUeFa5IY#iCKd})#FR_xBo8m&w|wvSywzf5QP?YEkQl4l zLzW*&In~tM%uNvIfzhnz%K4dZFF`y5Ydw3t9JO12e?cY+L?>n5o2}j%hfE4WGVl5l z=z&Za*q)!dF&X>)C=K>wI94p=+=*R>#>0^A1%?WRoZGQ%^+GxW>@9fZN_}Cp^%>GZ z(f6t8th;pg{b6t}0A>i7G?;55Og%W1#-{Nwr{oOuJr6V>g?TVplWYNb89De!K_4?mbH772Ts_A@H%cm-x^O1O4KB>>04w)jUE{&A*hY>CGt+UDQ E4YiPiiU0rr diff --git a/priv/static/static/font/fontello.1588419330867.svg b/priv/static/static/font/fontello.1588947937982.svg similarity index 98% rename from priv/static/static/font/fontello.1588419330867.svg rename to priv/static/static/font/fontello.1588947937982.svg index 71f81f435..e63fb7529 100644 --- a/priv/static/static/font/fontello.1588419330867.svg +++ b/priv/static/static/font/fontello.1588947937982.svg @@ -114,6 +114,8 @@ + + diff --git a/priv/static/static/font/fontello.1588419330867.ttf b/priv/static/static/font/fontello.1588947937982.ttf similarity index 90% rename from priv/static/static/font/fontello.1588419330867.ttf rename to priv/static/static/font/fontello.1588947937982.ttf index 7dc4f108b7be4e5c132da254f00e70a6463d8102..443801c4fc0b48e45cf0ae16472319b6b95eb52a 100644 GIT binary patch delta 720 zcmZvZT}V@L7{;IXe|FBy%^GStVazo@X4b{n*5+oIif(LbbRm*;Q3v;N8e2PTL(~GV zs|%;6B7z_&`hYH?Ltx;Aw}XssQ=(n88eQ#Jfmbf3br(OL_jxaWFYo$mdhmt{UCWCA zT>vmMmloys)@y?Ry#RRA+u)xs<=WdjUyLd?kkOu*zGfQCeB zF>ZeMBICy}1O8e+A%`q?o8L>W%|J3xIAZonQF)eWvya2o3|Nq%w2j z&Svo&5b6UkpB5KnT4{O)gdW!gu8Zl|)}wYa5ZVOTmYm7uUtM*nK%@Y$xSWm2<&jex zz{SGq-er2IOj9B}4XW$Yd2k2YX>e!+*fexx2hax_bZDq_R~!{r#Zz6W7OSOdx%#uZ zuQh9CZAcr@#7zTTGAOc>LU_M6;kAk8jl*IPN@B(yUg;|8+v)=*xBDOaFzP?+dG!{zg7mueH2jS v@y|4?M1nV(?A9Nh_v*g`5Kun^4IBlO?QoXSpgI{*N#Jvmn2o8m3BU0V8fd?d delta 495 zcmZXP&1(~35Qm?4ciGk^QjtO<2#r`HRzax2G$k)js~U4$I^2UsC^@T4I1U|?_V`T?bAD;xDB4>P~H%<#;k4bf_f)#FRI zK}-QN1>16#m$qMmcn;cb;buLq@9%vFGY-V(osxZTZFLsR3`CrgRdawtV8(#n(!#Cz zEjpcv)0=R$xwdmn zJeJdM+kH}X|Cam5wxwwaFp2Cq|&Bme*a diff --git a/priv/static/static/font/fontello.1588947937982.woff b/priv/static/static/font/fontello.1588947937982.woff new file mode 100644 index 0000000000000000000000000000000000000000..e96fea75766b8087fd2e064329a1e21500d2e522 GIT binary patch literal 13988 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 oELv0&C<{9 literal 0 HcmV?d00001 diff --git a/priv/static/static/font/fontello.1588947937982.woff2 b/priv/static/static/font/fontello.1588947937982.woff2 new file mode 100644 index 0000000000000000000000000000000000000000..50318a6703694b2888e6be5f00b39e91435e3105 GIT binary patch literal 11816 zcmV+@F4xg_Pew8T0RR9104^v14*&oF09hCS04>k}0RR9100000000000000000000 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 Wp?_x}4h)=p4)p!;5VXmQ10De4ugL!Z literal 0 HcmV?d00001 diff --git a/priv/static/static/fontello.1588419330867.css b/priv/static/static/fontello.1588947937982.css similarity index 88% rename from priv/static/static/fontello.1588419330867.css rename to priv/static/static/fontello.1588947937982.css index 198eff184..d3d77a8b5 100644 --- a/priv/static/static/fontello.1588419330867.css +++ b/priv/static/static/fontello.1588947937982.css @@ -1,11 +1,11 @@ @font-face { font-family: "Icons"; - src: url("./font/fontello.1588419330867.eot"); - src: url("./font/fontello.1588419330867.eot") format("embedded-opentype"), - url("./font/fontello.1588419330867.woff2") format("woff2"), - url("./font/fontello.1588419330867.woff") format("woff"), - url("./font/fontello.1588419330867.ttf") format("truetype"), - url("./font/fontello.1588419330867.svg") format("svg"); + src: url("./font/fontello.1588947937982.eot"); + src: url("./font/fontello.1588947937982.eot") format("embedded-opentype"), + url("./font/fontello.1588947937982.woff2") format("woff2"), + url("./font/fontello.1588947937982.woff") format("woff"), + url("./font/fontello.1588947937982.ttf") format("truetype"), + url("./font/fontello.1588947937982.svg") format("svg"); font-weight: normal; font-style: normal; } @@ -137,6 +137,8 @@ .icon-link::before { content: "\e823"; } +.icon-share::before { content: "\f1e0"; } + .icon-user::before { content: "\e824"; } .icon-ok::before { content: "\e827"; } diff --git a/priv/static/static/fontello.json b/priv/static/static/fontello.json index 5963b68b4..7f0e7cdd5 100755 --- a/priv/static/static/fontello.json +++ b/priv/static/static/fontello.json @@ -346,6 +346,12 @@ "code": 59427, "src": "fontawesome" }, + { + "uid": "4aad6bb50b02c18508aae9cbe14e784e", + "css": "share", + "code": 61920, + "src": "fontawesome" + }, { "uid": "8b80d36d4ef43889db10bc1f0dc9a862", "css": "user", diff --git a/priv/static/static/js/2.1c407059cd79fca99e19.js b/priv/static/static/js/2.18e4adec273c4ce867a8.js similarity index 80% rename from priv/static/static/js/2.1c407059cd79fca99e19.js rename to priv/static/static/js/2.18e4adec273c4ce867a8.js index 14018d92a..d191aa852 100644 --- a/priv/static/static/js/2.1c407059cd79fca99e19.js +++ b/priv/static/static/js/2.18e4adec273c4ce867a8.js @@ -1,2 +1,2 @@ -(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{585:function(t,e,i){var c=i(586);"string"==typeof c&&(c=[[t.i,c,""]]),c.locals&&(t.exports=c.locals);(0,i(4).default)("2eec4758",c,!0,{})},586:function(t,e,i){(t.exports=i(3)(!1)).push([t.i,".sticker-picker{width:100%}.sticker-picker .contents{min-height:250px}.sticker-picker .contents .sticker-picker-content{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:0 4px}.sticker-picker .contents .sticker-picker-content .sticker{display:-ms-flexbox;display:flex;-ms-flex:1 1 auto;flex:1 1 auto;margin:4px;width:56px;height:56px}.sticker-picker .contents .sticker-picker-content .sticker img{height:100%}.sticker-picker .contents .sticker-picker-content .sticker img:hover{filter:drop-shadow(0 0 5px var(--accent,#d8a070))}",""])},587:function(t,e,i){"use strict";i.r(e);var c=i(91),n={components:{TabSwitcher:i(53).a},data:function(){return{meta:{stickers:[]},path:""}},computed:{pack:function(){return this.$store.state.instance.stickers||[]}},methods:{clear:function(){this.meta={stickers:[]}},pick:function(t,e){var i=this,n=this.$store;fetch(t).then((function(t){t.blob().then((function(t){var a=new File([t],e,{mimetype:"image/png"}),r=new FormData;r.append("file",a),c.a.uploadMedia({store:n,formData:r}).then((function(t){i.$emit("uploaded",t),i.clear()}),(function(t){console.warn("Can't attach sticker"),console.warn(t),i.$emit("upload-failed","default")}))}))}))}}},a=i(0);var r=function(t){i(585)},s=Object(a.a)(n,(function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"sticker-picker"},[i("tab-switcher",{staticClass:"tab-switcher",attrs:{"render-only-focused":!0,"scrollable-tabs":""}},t._l(t.pack,(function(e){return i("div",{key:e.path,staticClass:"sticker-picker-content",attrs:{"image-tooltip":e.meta.title,image:e.path+e.meta.tabIcon}},t._l(e.meta.stickers,(function(c){return i("div",{key:c,staticClass:"sticker",on:{click:function(i){return i.stopPropagation(),i.preventDefault(),t.pick(e.path+c,e.meta.title)}}},[i("img",{attrs:{src:e.path+c}})])})),0)})),0)],1)}),[],!1,r,null,null);e.default=s.exports}}]); -//# sourceMappingURL=2.1c407059cd79fca99e19.js.map \ No newline at end of file +(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{587:function(t,e,i){var c=i(588);"string"==typeof c&&(c=[[t.i,c,""]]),c.locals&&(t.exports=c.locals);(0,i(3).default)("2eec4758",c,!0,{})},588:function(t,e,i){(t.exports=i(2)(!1)).push([t.i,".sticker-picker{width:100%}.sticker-picker .contents{min-height:250px}.sticker-picker .contents .sticker-picker-content{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:0 4px}.sticker-picker .contents .sticker-picker-content .sticker{display:-ms-flexbox;display:flex;-ms-flex:1 1 auto;flex:1 1 auto;margin:4px;width:56px;height:56px}.sticker-picker .contents .sticker-picker-content .sticker img{height:100%}.sticker-picker .contents .sticker-picker-content .sticker img:hover{filter:drop-shadow(0 0 5px var(--accent,#d8a070))}",""])},589:function(t,e,i){"use strict";i.r(e);var c=i(91),n={components:{TabSwitcher:i(53).a},data:function(){return{meta:{stickers:[]},path:""}},computed:{pack:function(){return this.$store.state.instance.stickers||[]}},methods:{clear:function(){this.meta={stickers:[]}},pick:function(t,e){var i=this,n=this.$store;fetch(t).then((function(t){t.blob().then((function(t){var a=new File([t],e,{mimetype:"image/png"}),r=new FormData;r.append("file",a),c.a.uploadMedia({store:n,formData:r}).then((function(t){i.$emit("uploaded",t),i.clear()}),(function(t){console.warn("Can't attach sticker"),console.warn(t),i.$emit("upload-failed","default")}))}))}))}}},a=i(0);var r=function(t){i(587)},s=Object(a.a)(n,(function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"sticker-picker"},[i("tab-switcher",{staticClass:"tab-switcher",attrs:{"render-only-focused":!0,"scrollable-tabs":""}},t._l(t.pack,(function(e){return i("div",{key:e.path,staticClass:"sticker-picker-content",attrs:{"image-tooltip":e.meta.title,image:e.path+e.meta.tabIcon}},t._l(e.meta.stickers,(function(c){return i("div",{key:c,staticClass:"sticker",on:{click:function(i){return i.stopPropagation(),i.preventDefault(),t.pick(e.path+c,e.meta.title)}}},[i("img",{attrs:{src:e.path+c}})])})),0)})),0)],1)}),[],!1,r,null,null);e.default=s.exports}}]); +//# sourceMappingURL=2.18e4adec273c4ce867a8.js.map \ No newline at end of file diff --git a/priv/static/static/js/2.1c407059cd79fca99e19.js.map b/priv/static/static/js/2.18e4adec273c4ce867a8.js.map similarity index 99% rename from priv/static/static/js/2.1c407059cd79fca99e19.js.map rename to priv/static/static/js/2.18e4adec273c4ce867a8.js.map index cfee79ea8..a7f98bfef 100644 --- a/priv/static/static/js/2.1c407059cd79fca99e19.js.map +++ b/priv/static/static/js/2.18e4adec273c4ce867a8.js.map @@ -1 +1 @@ -{"version":3,"sources":["webpack:///./src/components/sticker_picker/sticker_picker.vue?e513","webpack:///./src/components/sticker_picker/sticker_picker.vue?1909","webpack:///./src/components/sticker_picker/sticker_picker.js","webpack:///./src/components/sticker_picker/sticker_picker.vue","webpack:///./src/components/sticker_picker/sticker_picker.vue?7504"],"names":["content","module","i","locals","exports","add","default","push","StickerPicker","components","TabSwitcher","data","meta","stickers","path","computed","pack","this","$store","state","instance","methods","clear","pick","sticker","name","store","fetch","then","res","blob","file","File","mimetype","formData","FormData","append","statusPosterService","uploadMedia","fileData","$emit","error","console","warn","__vue_styles__","context","Component","_vm","_h","$createElement","_c","_self","staticClass","attrs","_l","stickerpack","key","title","tabIcon","on","$event","stopPropagation","preventDefault"],"mappings":"6EAGA,IAAIA,EAAU,EAAQ,KACA,iBAAZA,IAAsBA,EAAU,CAAC,CAACC,EAAOC,EAAIF,EAAS,MAC7DA,EAAQG,SAAQF,EAAOG,QAAUJ,EAAQG,SAG/BE,EADH,EAAQ,GAAkEC,SACnE,WAAYN,GAAS,EAAM,K,qBCRlCC,EAAOG,QAAU,EAAQ,EAAR,EAA4D,IAK/EG,KAAK,CAACN,EAAOC,EAAI,4iBAA6iB,M,oDC8CvjBM,EA/CO,CACpBC,WAAY,CACVC,Y,MAAAA,GAEFC,KAJoB,WAKlB,MAAO,CACLC,KAAM,CACJC,SAAU,IAEZC,KAAM,KAGVC,SAAU,CACRC,KADQ,WAEN,OAAOC,KAAKC,OAAOC,MAAMC,SAASP,UAAY,KAGlDQ,QAAS,CACPC,MADO,WAELL,KAAKL,KAAO,CACVC,SAAU,KAGdU,KANO,SAMDC,EAASC,GAAM,WACbC,EAAQT,KAAKC,OAEnBS,MAAMH,GACHI,MAAK,SAACC,GACLA,EAAIC,OAAOF,MAAK,SAACE,GACf,IAAIC,EAAO,IAAIC,KAAK,CAACF,GAAOL,EAAM,CAAEQ,SAAU,cAC1CC,EAAW,IAAIC,SACnBD,EAASE,OAAO,OAAQL,GACxBM,IAAoBC,YAAY,CAAEZ,QAAOQ,aACtCN,MAAK,SAACW,GACL,EAAKC,MAAM,WAAYD,GACvB,EAAKjB,WACJ,SAACmB,GACFC,QAAQC,KAAK,wBACbD,QAAQC,KAAKF,GACb,EAAKD,MAAM,gBAAiB,uB,OCnC5C,IAEII,EAVJ,SAAsBC,GACpB,EAAQ,MAeNC,EAAY,YACd,GCjBW,WAAa,IAAIC,EAAI9B,KAAS+B,EAAGD,EAAIE,eAAmBC,EAAGH,EAAII,MAAMD,IAAIF,EAAG,OAAOE,EAAG,MAAM,CAACE,YAAY,kBAAkB,CAACF,EAAG,eAAe,CAACE,YAAY,eAAeC,MAAM,CAAC,uBAAsB,EAAK,kBAAkB,KAAKN,EAAIO,GAAIP,EAAQ,MAAE,SAASQ,GAAa,OAAOL,EAAG,MAAM,CAACM,IAAID,EAAYzC,KAAKsC,YAAY,yBAAyBC,MAAM,CAAC,gBAAgBE,EAAY3C,KAAK6C,MAAM,MAAQF,EAAYzC,KAAOyC,EAAY3C,KAAK8C,UAAUX,EAAIO,GAAIC,EAAY3C,KAAa,UAAE,SAASY,GAAS,OAAO0B,EAAG,MAAM,CAACM,IAAIhC,EAAQ4B,YAAY,UAAUO,GAAG,CAAC,MAAQ,SAASC,GAAyD,OAAjDA,EAAOC,kBAAkBD,EAAOE,iBAAwBf,EAAIxB,KAAKgC,EAAYzC,KAAOU,EAAS+B,EAAY3C,KAAK6C,UAAU,CAACP,EAAG,MAAM,CAACG,MAAM,CAAC,IAAME,EAAYzC,KAAOU,UAAe,MAAK,IAAI,KACjvB,IDOY,EAahCoB,EAToB,KAEU,MAYjB,UAAAE,EAAiB","file":"static/js/2.1c407059cd79fca99e19.js","sourcesContent":["// style-loader: Adds some css to the DOM by adding a \n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./checkbox.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!../../../node_modules/vue-loader/lib/selector?type=script&index=0!./checkbox.vue\"\nimport __vue_script__ from \"!!babel-loader!../../../node_modules/vue-loader/lib/selector?type=script&index=0!./checkbox.vue\"\n/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-01a5cae8\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./checkbox.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('label',{staticClass:\"checkbox\",class:{ disabled: _vm.disabled, indeterminate: _vm.indeterminate }},[_c('input',{attrs:{\"type\":\"checkbox\",\"disabled\":_vm.disabled},domProps:{\"checked\":_vm.checked,\"indeterminate\":_vm.indeterminate},on:{\"change\":function($event){return _vm.$emit('change', $event.target.checked)}}}),_vm._v(\" \"),_c('i',{staticClass:\"checkbox-indicator\"}),_vm._v(\" \"),(!!_vm.$slots.default)?_c('span',{staticClass:\"label\"},[_vm._t(\"default\")],2):_vm._e()])}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import { filter, sortBy, includes } from 'lodash'\n\nexport const notificationsFromStore = store => store.state.statuses.notifications.data\n\nexport const visibleTypes = store => ([\n store.state.config.notificationVisibility.likes && 'like',\n store.state.config.notificationVisibility.mentions && 'mention',\n store.state.config.notificationVisibility.repeats && 'repeat',\n store.state.config.notificationVisibility.follows && 'follow',\n store.state.config.notificationVisibility.followRequest && 'follow_request',\n store.state.config.notificationVisibility.moves && 'move',\n store.state.config.notificationVisibility.emojiReactions && 'pleroma:emoji_reaction'\n].filter(_ => _))\n\nconst statusNotifications = ['like', 'mention', 'repeat', 'pleroma:emoji_reaction']\n\nexport const isStatusNotification = (type) => includes(statusNotifications, type)\n\nconst sortById = (a, b) => {\n const seqA = Number(a.id)\n const seqB = Number(b.id)\n const isSeqA = !Number.isNaN(seqA)\n const isSeqB = !Number.isNaN(seqB)\n if (isSeqA && isSeqB) {\n return seqA > seqB ? -1 : 1\n } else if (isSeqA && !isSeqB) {\n return 1\n } else if (!isSeqA && isSeqB) {\n return -1\n } else {\n return a.id > b.id ? -1 : 1\n }\n}\n\nexport const filteredNotificationsFromStore = (store, types) => {\n // map is just to clone the array since sort mutates it and it causes some issues\n let sortedNotifications = notificationsFromStore(store).map(_ => _).sort(sortById)\n sortedNotifications = sortBy(sortedNotifications, 'seen')\n return sortedNotifications.filter(\n (notification) => (types || visibleTypes(store)).includes(notification.type)\n )\n}\n\nexport const unseenNotificationsFromStore = store =>\n filter(filteredNotificationsFromStore(store), ({ seen }) => !seen)\n","import { includes } from 'lodash'\n\nconst generateProfileLink = (id, screenName, restrictedNicknames) => {\n const complicated = !screenName || (isExternal(screenName) || includes(restrictedNicknames, screenName))\n return {\n name: (complicated ? 'external-user-profile' : 'user-profile'),\n params: (complicated ? { id } : { name: screenName })\n }\n}\n\nconst isExternal = screenName => screenName && screenName.includes('@')\n\nexport default generateProfileLink\n","// TODO this func might as well take the entire file and use its mimetype\n// or the entire service could be just mimetype service that only operates\n// on mimetypes and not files. Currently the naming is confusing.\nconst fileType = mimetype => {\n if (mimetype.match(/text\\/html/)) {\n return 'html'\n }\n\n if (mimetype.match(/image/)) {\n return 'image'\n }\n\n if (mimetype.match(/video/)) {\n return 'video'\n }\n\n if (mimetype.match(/audio/)) {\n return 'audio'\n }\n\n return 'unknown'\n}\n\nconst fileMatchesSomeType = (types, file) =>\n types.some(type => fileType(file.mimetype) === type)\n\nconst fileTypeService = {\n fileType,\n fileMatchesSomeType\n}\n\nexport default fileTypeService\n","const DialogModal = {\n props: {\n darkOverlay: {\n default: true,\n type: Boolean\n },\n onCancel: {\n default: () => {},\n type: Function\n }\n }\n}\n\nexport default DialogModal\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./dialog_modal.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./dialog_modal.js\"\nimport __vue_script__ from \"!!babel-loader!./dialog_modal.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-70b9d662\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./dialog_modal.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('span',{class:{ 'dark-overlay': _vm.darkOverlay },on:{\"click\":function($event){if($event.target !== $event.currentTarget){ return null; }$event.stopPropagation();return _vm.onCancel()}}},[_c('div',{staticClass:\"dialog-modal panel panel-default\",on:{\"click\":function($event){$event.stopPropagation();}}},[_c('div',{staticClass:\"panel-heading dialog-modal-heading\"},[_c('div',{staticClass:\"title\"},[_vm._t(\"header\")],2)]),_vm._v(\" \"),_c('div',{staticClass:\"dialog-modal-content\"},[_vm._t(\"default\")],2),_vm._v(\" \"),_c('div',{staticClass:\"dialog-modal-footer user-interactions panel-footer\"},[_vm._t(\"footer\")],2)])])}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import DialogModal from '../dialog_modal/dialog_modal.vue'\nimport Popover from '../popover/popover.vue'\n\nconst FORCE_NSFW = 'mrf_tag:media-force-nsfw'\nconst STRIP_MEDIA = 'mrf_tag:media-strip'\nconst FORCE_UNLISTED = 'mrf_tag:force-unlisted'\nconst DISABLE_REMOTE_SUBSCRIPTION = 'mrf_tag:disable-remote-subscription'\nconst DISABLE_ANY_SUBSCRIPTION = 'mrf_tag:disable-any-subscription'\nconst SANDBOX = 'mrf_tag:sandbox'\nconst QUARANTINE = 'mrf_tag:quarantine'\n\nconst ModerationTools = {\n props: [\n 'user'\n ],\n data () {\n return {\n tags: {\n FORCE_NSFW,\n STRIP_MEDIA,\n FORCE_UNLISTED,\n DISABLE_REMOTE_SUBSCRIPTION,\n DISABLE_ANY_SUBSCRIPTION,\n SANDBOX,\n QUARANTINE\n },\n showDeleteUserDialog: false,\n toggled: false\n }\n },\n components: {\n DialogModal,\n Popover\n },\n computed: {\n tagsSet () {\n return new Set(this.user.tags)\n },\n hasTagPolicy () {\n return this.$store.state.instance.tagPolicyAvailable\n }\n },\n methods: {\n hasTag (tagName) {\n return this.tagsSet.has(tagName)\n },\n toggleTag (tag) {\n const store = this.$store\n if (this.tagsSet.has(tag)) {\n store.state.api.backendInteractor.untagUser({ user: this.user, tag }).then(response => {\n if (!response.ok) { return }\n store.commit('untagUser', { user: this.user, tag })\n })\n } else {\n store.state.api.backendInteractor.tagUser({ user: this.user, tag }).then(response => {\n if (!response.ok) { return }\n store.commit('tagUser', { user: this.user, tag })\n })\n }\n },\n toggleRight (right) {\n const store = this.$store\n if (this.user.rights[right]) {\n store.state.api.backendInteractor.deleteRight({ user: this.user, right }).then(response => {\n if (!response.ok) { return }\n store.commit('updateRight', { user: this.user, right, value: false })\n })\n } else {\n store.state.api.backendInteractor.addRight({ user: this.user, right }).then(response => {\n if (!response.ok) { return }\n store.commit('updateRight', { user: this.user, right, value: true })\n })\n }\n },\n toggleActivationStatus () {\n this.$store.dispatch('toggleActivationStatus', { user: this.user })\n },\n deleteUserDialog (show) {\n this.showDeleteUserDialog = show\n },\n deleteUser () {\n const store = this.$store\n const user = this.user\n const { id, name } = user\n store.state.api.backendInteractor.deleteUser({ user })\n .then(e => {\n this.$store.dispatch('markStatusesAsDeleted', status => user.id === status.user.id)\n const isProfile = this.$route.name === 'external-user-profile' || this.$route.name === 'user-profile'\n const isTargetUser = this.$route.params.name === name || this.$route.params.id === id\n if (isProfile && isTargetUser) {\n window.history.back()\n }\n })\n },\n setToggled (value) {\n this.toggled = value\n }\n }\n}\n\nexport default ModerationTools\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./moderation_tools.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./moderation_tools.js\"\nimport __vue_script__ from \"!!babel-loader!./moderation_tools.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-168f1ca6\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./moderation_tools.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_c('Popover',{staticClass:\"moderation-tools-popover\",attrs:{\"trigger\":\"click\",\"placement\":\"bottom\",\"offset\":{ y: 5 }},on:{\"show\":function($event){return _vm.setToggled(true)},\"close\":function($event){return _vm.setToggled(false)}}},[_c('div',{attrs:{\"slot\":\"content\"},slot:\"content\"},[_c('div',{staticClass:\"dropdown-menu\"},[(_vm.user.is_local)?_c('span',[_c('button',{staticClass:\"dropdown-item\",on:{\"click\":function($event){return _vm.toggleRight(\"admin\")}}},[_vm._v(\"\\n \"+_vm._s(_vm.$t(!!_vm.user.rights.admin ? 'user_card.admin_menu.revoke_admin' : 'user_card.admin_menu.grant_admin'))+\"\\n \")]),_vm._v(\" \"),_c('button',{staticClass:\"dropdown-item\",on:{\"click\":function($event){return _vm.toggleRight(\"moderator\")}}},[_vm._v(\"\\n \"+_vm._s(_vm.$t(!!_vm.user.rights.moderator ? 'user_card.admin_menu.revoke_moderator' : 'user_card.admin_menu.grant_moderator'))+\"\\n \")]),_vm._v(\" \"),_c('div',{staticClass:\"dropdown-divider\",attrs:{\"role\":\"separator\"}})]):_vm._e(),_vm._v(\" \"),_c('button',{staticClass:\"dropdown-item\",on:{\"click\":function($event){return _vm.toggleActivationStatus()}}},[_vm._v(\"\\n \"+_vm._s(_vm.$t(!!_vm.user.deactivated ? 'user_card.admin_menu.activate_account' : 'user_card.admin_menu.deactivate_account'))+\"\\n \")]),_vm._v(\" \"),_c('button',{staticClass:\"dropdown-item\",on:{\"click\":function($event){return _vm.deleteUserDialog(true)}}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.admin_menu.delete_account'))+\"\\n \")]),_vm._v(\" \"),(_vm.hasTagPolicy)?_c('div',{staticClass:\"dropdown-divider\",attrs:{\"role\":\"separator\"}}):_vm._e(),_vm._v(\" \"),(_vm.hasTagPolicy)?_c('span',[_c('button',{staticClass:\"dropdown-item\",on:{\"click\":function($event){return _vm.toggleTag(_vm.tags.FORCE_NSFW)}}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.admin_menu.force_nsfw'))+\"\\n \"),_c('span',{staticClass:\"menu-checkbox\",class:{ 'menu-checkbox-checked': _vm.hasTag(_vm.tags.FORCE_NSFW) }})]),_vm._v(\" \"),_c('button',{staticClass:\"dropdown-item\",on:{\"click\":function($event){return _vm.toggleTag(_vm.tags.STRIP_MEDIA)}}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.admin_menu.strip_media'))+\"\\n \"),_c('span',{staticClass:\"menu-checkbox\",class:{ 'menu-checkbox-checked': _vm.hasTag(_vm.tags.STRIP_MEDIA) }})]),_vm._v(\" \"),_c('button',{staticClass:\"dropdown-item\",on:{\"click\":function($event){return _vm.toggleTag(_vm.tags.FORCE_UNLISTED)}}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.admin_menu.force_unlisted'))+\"\\n \"),_c('span',{staticClass:\"menu-checkbox\",class:{ 'menu-checkbox-checked': _vm.hasTag(_vm.tags.FORCE_UNLISTED) }})]),_vm._v(\" \"),_c('button',{staticClass:\"dropdown-item\",on:{\"click\":function($event){return _vm.toggleTag(_vm.tags.SANDBOX)}}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.admin_menu.sandbox'))+\"\\n \"),_c('span',{staticClass:\"menu-checkbox\",class:{ 'menu-checkbox-checked': _vm.hasTag(_vm.tags.SANDBOX) }})]),_vm._v(\" \"),(_vm.user.is_local)?_c('button',{staticClass:\"dropdown-item\",on:{\"click\":function($event){return _vm.toggleTag(_vm.tags.DISABLE_REMOTE_SUBSCRIPTION)}}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.admin_menu.disable_remote_subscription'))+\"\\n \"),_c('span',{staticClass:\"menu-checkbox\",class:{ 'menu-checkbox-checked': _vm.hasTag(_vm.tags.DISABLE_REMOTE_SUBSCRIPTION) }})]):_vm._e(),_vm._v(\" \"),(_vm.user.is_local)?_c('button',{staticClass:\"dropdown-item\",on:{\"click\":function($event){return _vm.toggleTag(_vm.tags.DISABLE_ANY_SUBSCRIPTION)}}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.admin_menu.disable_any_subscription'))+\"\\n \"),_c('span',{staticClass:\"menu-checkbox\",class:{ 'menu-checkbox-checked': _vm.hasTag(_vm.tags.DISABLE_ANY_SUBSCRIPTION) }})]):_vm._e(),_vm._v(\" \"),(_vm.user.is_local)?_c('button',{staticClass:\"dropdown-item\",on:{\"click\":function($event){return _vm.toggleTag(_vm.tags.QUARANTINE)}}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.admin_menu.quarantine'))+\"\\n \"),_c('span',{staticClass:\"menu-checkbox\",class:{ 'menu-checkbox-checked': _vm.hasTag(_vm.tags.QUARANTINE) }})]):_vm._e()]):_vm._e()])]),_vm._v(\" \"),_c('button',{staticClass:\"btn btn-default btn-block\",class:{ toggled: _vm.toggled },attrs:{\"slot\":\"trigger\"},slot:\"trigger\"},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.admin_menu.moderation'))+\"\\n \")])]),_vm._v(\" \"),_c('portal',{attrs:{\"to\":\"modal\"}},[(_vm.showDeleteUserDialog)?_c('DialogModal',{attrs:{\"on-cancel\":_vm.deleteUserDialog.bind(this, false)}},[_c('template',{slot:\"header\"},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.admin_menu.delete_user'))+\"\\n \")]),_vm._v(\" \"),_c('p',[_vm._v(_vm._s(_vm.$t('user_card.admin_menu.delete_user_confirmation')))]),_vm._v(\" \"),_c('template',{slot:\"footer\"},[_c('button',{staticClass:\"btn btn-default\",on:{\"click\":function($event){return _vm.deleteUserDialog(false)}}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('general.cancel'))+\"\\n \")]),_vm._v(\" \"),_c('button',{staticClass:\"btn btn-default danger\",on:{\"click\":function($event){return _vm.deleteUser()}}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.admin_menu.delete_user'))+\"\\n \")])])],2):_vm._e()],1)],1)}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import ProgressButton from '../progress_button/progress_button.vue'\nimport Popover from '../popover/popover.vue'\n\nconst AccountActions = {\n props: [\n 'user', 'relationship'\n ],\n data () {\n return { }\n },\n components: {\n ProgressButton,\n Popover\n },\n methods: {\n showRepeats () {\n this.$store.dispatch('showReblogs', this.user.id)\n },\n hideRepeats () {\n this.$store.dispatch('hideReblogs', this.user.id)\n },\n blockUser () {\n this.$store.dispatch('blockUser', this.user.id)\n },\n unblockUser () {\n this.$store.dispatch('unblockUser', this.user.id)\n },\n reportUser () {\n this.$store.dispatch('openUserReportingModal', this.user.id)\n }\n }\n}\n\nexport default AccountActions\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./account_actions.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./account_actions.js\"\nimport __vue_script__ from \"!!babel-loader!./account_actions.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-bf5e6e30\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./account_actions.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"account-actions\"},[_c('Popover',{attrs:{\"trigger\":\"click\",\"placement\":\"bottom\"}},[_c('div',{staticClass:\"account-tools-popover\",attrs:{\"slot\":\"content\"},slot:\"content\"},[_c('div',{staticClass:\"dropdown-menu\"},[(_vm.relationship.following)?[(_vm.relationship.showing_reblogs)?_c('button',{staticClass:\"btn btn-default dropdown-item\",on:{\"click\":_vm.hideRepeats}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.hide_repeats'))+\"\\n \")]):_vm._e(),_vm._v(\" \"),(!_vm.relationship.showing_reblogs)?_c('button',{staticClass:\"btn btn-default dropdown-item\",on:{\"click\":_vm.showRepeats}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.show_repeats'))+\"\\n \")]):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"dropdown-divider\",attrs:{\"role\":\"separator\"}})]:_vm._e(),_vm._v(\" \"),(_vm.relationship.blocking)?_c('button',{staticClass:\"btn btn-default btn-block dropdown-item\",on:{\"click\":_vm.unblockUser}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.unblock'))+\"\\n \")]):_c('button',{staticClass:\"btn btn-default btn-block dropdown-item\",on:{\"click\":_vm.blockUser}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.block'))+\"\\n \")]),_vm._v(\" \"),_c('button',{staticClass:\"btn btn-default btn-block dropdown-item\",on:{\"click\":_vm.reportUser}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.report'))+\"\\n \")])],2)]),_vm._v(\" \"),_c('div',{staticClass:\"btn btn-default ellipsis-button\",attrs:{\"slot\":\"trigger\"},slot:\"trigger\"},[_c('i',{staticClass:\"icon-ellipsis trigger-button\"})])])],1)}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import UserAvatar from '../user_avatar/user_avatar.vue'\nimport RemoteFollow from '../remote_follow/remote_follow.vue'\nimport ProgressButton from '../progress_button/progress_button.vue'\nimport FollowButton from '../follow_button/follow_button.vue'\nimport ModerationTools from '../moderation_tools/moderation_tools.vue'\nimport AccountActions from '../account_actions/account_actions.vue'\nimport generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'\nimport { mapGetters } from 'vuex'\n\nexport default {\n props: [\n 'userId', 'switcher', 'selected', 'hideBio', 'rounded', 'bordered', 'allowZoomingAvatar'\n ],\n data () {\n return {\n followRequestInProgress: false,\n betterShadow: this.$store.state.interface.browserSupport.cssFilter\n }\n },\n created () {\n this.$store.dispatch('fetchUserRelationship', this.user.id)\n },\n computed: {\n user () {\n return this.$store.getters.findUser(this.userId)\n },\n relationship () {\n return this.$store.getters.relationship(this.userId)\n },\n classes () {\n return [{\n 'user-card-rounded-t': this.rounded === 'top', // set border-top-left-radius and border-top-right-radius\n 'user-card-rounded': this.rounded === true, // set border-radius for all sides\n 'user-card-bordered': this.bordered === true // set border for all sides\n }]\n },\n style () {\n return {\n backgroundImage: [\n `linear-gradient(to bottom, var(--profileTint), var(--profileTint))`,\n `url(${this.user.cover_photo})`\n ].join(', ')\n }\n },\n isOtherUser () {\n return this.user.id !== this.$store.state.users.currentUser.id\n },\n subscribeUrl () {\n // eslint-disable-next-line no-undef\n const serverUrl = new URL(this.user.statusnet_profile_url)\n return `${serverUrl.protocol}//${serverUrl.host}/main/ostatus`\n },\n loggedIn () {\n return this.$store.state.users.currentUser\n },\n dailyAvg () {\n const days = Math.ceil((new Date() - new Date(this.user.created_at)) / (60 * 60 * 24 * 1000))\n return Math.round(this.user.statuses_count / days)\n },\n userHighlightType: {\n get () {\n const data = this.$store.getters.mergedConfig.highlight[this.user.screen_name]\n return (data && data.type) || 'disabled'\n },\n set (type) {\n const data = this.$store.getters.mergedConfig.highlight[this.user.screen_name]\n if (type !== 'disabled') {\n this.$store.dispatch('setHighlight', { user: this.user.screen_name, color: (data && data.color) || '#FFFFFF', type })\n } else {\n this.$store.dispatch('setHighlight', { user: this.user.screen_name, color: undefined })\n }\n },\n ...mapGetters(['mergedConfig'])\n },\n userHighlightColor: {\n get () {\n const data = this.$store.getters.mergedConfig.highlight[this.user.screen_name]\n return data && data.color\n },\n set (color) {\n this.$store.dispatch('setHighlight', { user: this.user.screen_name, color })\n }\n },\n visibleRole () {\n const rights = this.user.rights\n if (!rights) { return }\n const validRole = rights.admin || rights.moderator\n const roleTitle = rights.admin ? 'admin' : 'moderator'\n return validRole && roleTitle\n },\n hideFollowsCount () {\n return this.isOtherUser && this.user.hide_follows_count\n },\n hideFollowersCount () {\n return this.isOtherUser && this.user.hide_followers_count\n },\n ...mapGetters(['mergedConfig'])\n },\n components: {\n UserAvatar,\n RemoteFollow,\n ModerationTools,\n AccountActions,\n ProgressButton,\n FollowButton\n },\n methods: {\n muteUser () {\n this.$store.dispatch('muteUser', this.user.id)\n },\n unmuteUser () {\n this.$store.dispatch('unmuteUser', this.user.id)\n },\n subscribeUser () {\n return this.$store.dispatch('subscribeUser', this.user.id)\n },\n unsubscribeUser () {\n return this.$store.dispatch('unsubscribeUser', this.user.id)\n },\n setProfileView (v) {\n if (this.switcher) {\n const store = this.$store\n store.commit('setProfileView', { v })\n }\n },\n linkClicked ({ target }) {\n if (target.tagName === 'SPAN') {\n target = target.parentNode\n }\n if (target.tagName === 'A') {\n window.open(target.href, '_blank')\n }\n },\n userProfileLink (user) {\n return generateProfileLink(\n user.id, user.screen_name,\n this.$store.state.instance.restrictedNicknames\n )\n },\n zoomAvatar () {\n const attachment = {\n url: this.user.profile_image_url_original,\n mimetype: 'image'\n }\n this.$store.dispatch('setMedia', [attachment])\n this.$store.dispatch('setCurrent', attachment)\n },\n mentionUser () {\n this.$store.dispatch('openPostStatusModal', { replyTo: true, repliedUser: this.user })\n }\n }\n}\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./user_card.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./user_card.js\"\nimport __vue_script__ from \"!!babel-loader!./user_card.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-4d895630\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./user_card.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"user-card\",class:_vm.classes},[_c('div',{staticClass:\"background-image\",class:{ 'hide-bio': _vm.hideBio },style:(_vm.style)}),_vm._v(\" \"),_c('div',{staticClass:\"panel-heading\"},[_c('div',{staticClass:\"user-info\"},[_c('div',{staticClass:\"container\"},[(_vm.allowZoomingAvatar)?_c('a',{staticClass:\"user-info-avatar-link\",on:{\"click\":_vm.zoomAvatar}},[_c('UserAvatar',{attrs:{\"better-shadow\":_vm.betterShadow,\"user\":_vm.user}}),_vm._v(\" \"),_vm._m(0)],1):_c('router-link',{attrs:{\"to\":_vm.userProfileLink(_vm.user)}},[_c('UserAvatar',{attrs:{\"better-shadow\":_vm.betterShadow,\"user\":_vm.user}})],1),_vm._v(\" \"),_c('div',{staticClass:\"user-summary\"},[_c('div',{staticClass:\"top-line\"},[(_vm.user.name_html)?_c('div',{staticClass:\"user-name\",attrs:{\"title\":_vm.user.name},domProps:{\"innerHTML\":_vm._s(_vm.user.name_html)}}):_c('div',{staticClass:\"user-name\",attrs:{\"title\":_vm.user.name}},[_vm._v(\"\\n \"+_vm._s(_vm.user.name)+\"\\n \")]),_vm._v(\" \"),(!_vm.isOtherUser)?_c('router-link',{attrs:{\"to\":{ name: 'user-settings' }}},[_c('i',{staticClass:\"button-icon icon-wrench usersettings\",attrs:{\"title\":_vm.$t('tool_tip.user_settings')}})]):_vm._e(),_vm._v(\" \"),(_vm.isOtherUser && !_vm.user.is_local)?_c('a',{attrs:{\"href\":_vm.user.statusnet_profile_url,\"target\":\"_blank\"}},[_c('i',{staticClass:\"icon-link-ext usersettings\"})]):_vm._e(),_vm._v(\" \"),(_vm.isOtherUser && _vm.loggedIn)?_c('AccountActions',{attrs:{\"user\":_vm.user,\"relationship\":_vm.relationship}}):_vm._e()],1),_vm._v(\" \"),_c('div',{staticClass:\"bottom-line\"},[_c('router-link',{staticClass:\"user-screen-name\",attrs:{\"to\":_vm.userProfileLink(_vm.user)}},[_vm._v(\"\\n @\"+_vm._s(_vm.user.screen_name)+\"\\n \")]),_vm._v(\" \"),(!_vm.hideBio && !!_vm.visibleRole)?_c('span',{staticClass:\"alert staff\"},[_vm._v(_vm._s(_vm.visibleRole))]):_vm._e(),_vm._v(\" \"),(_vm.user.locked)?_c('span',[_c('i',{staticClass:\"icon icon-lock\"})]):_vm._e(),_vm._v(\" \"),(!_vm.mergedConfig.hideUserStats && !_vm.hideBio)?_c('span',{staticClass:\"dailyAvg\"},[_vm._v(_vm._s(_vm.dailyAvg)+\" \"+_vm._s(_vm.$t('user_card.per_day')))]):_vm._e()],1)])],1),_vm._v(\" \"),_c('div',{staticClass:\"user-meta\"},[(_vm.relationship.followed_by && _vm.loggedIn && _vm.isOtherUser)?_c('div',{staticClass:\"following\"},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.follows_you'))+\"\\n \")]):_vm._e(),_vm._v(\" \"),(_vm.isOtherUser && (_vm.loggedIn || !_vm.switcher))?_c('div',{staticClass:\"highlighter\"},[(_vm.userHighlightType !== 'disabled')?_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.userHighlightColor),expression:\"userHighlightColor\"}],staticClass:\"userHighlightText\",attrs:{\"id\":'userHighlightColorTx'+_vm.user.id,\"type\":\"text\"},domProps:{\"value\":(_vm.userHighlightColor)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.userHighlightColor=$event.target.value}}}):_vm._e(),_vm._v(\" \"),(_vm.userHighlightType !== 'disabled')?_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.userHighlightColor),expression:\"userHighlightColor\"}],staticClass:\"userHighlightCl\",attrs:{\"id\":'userHighlightColor'+_vm.user.id,\"type\":\"color\"},domProps:{\"value\":(_vm.userHighlightColor)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.userHighlightColor=$event.target.value}}}):_vm._e(),_vm._v(\" \"),_c('label',{staticClass:\"userHighlightSel select\",attrs:{\"for\":\"style-switcher\"}},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.userHighlightType),expression:\"userHighlightType\"}],staticClass:\"userHighlightSel\",attrs:{\"id\":'userHighlightSel'+_vm.user.id},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.userHighlightType=$event.target.multiple ? $$selectedVal : $$selectedVal[0]}}},[_c('option',{attrs:{\"value\":\"disabled\"}},[_vm._v(\"No highlight\")]),_vm._v(\" \"),_c('option',{attrs:{\"value\":\"solid\"}},[_vm._v(\"Solid bg\")]),_vm._v(\" \"),_c('option',{attrs:{\"value\":\"striped\"}},[_vm._v(\"Striped bg\")]),_vm._v(\" \"),_c('option',{attrs:{\"value\":\"side\"}},[_vm._v(\"Side stripe\")])]),_vm._v(\" \"),_c('i',{staticClass:\"icon-down-open\"})])]):_vm._e()]),_vm._v(\" \"),(_vm.loggedIn && _vm.isOtherUser)?_c('div',{staticClass:\"user-interactions\"},[_c('div',{staticClass:\"btn-group\"},[_c('FollowButton',{attrs:{\"relationship\":_vm.relationship}}),_vm._v(\" \"),(_vm.relationship.following)?[(!_vm.relationship.subscribing)?_c('ProgressButton',{staticClass:\"btn btn-default\",attrs:{\"click\":_vm.subscribeUser,\"title\":_vm.$t('user_card.subscribe')}},[_c('i',{staticClass:\"icon-bell-alt\"})]):_c('ProgressButton',{staticClass:\"btn btn-default toggled\",attrs:{\"click\":_vm.unsubscribeUser,\"title\":_vm.$t('user_card.unsubscribe')}},[_c('i',{staticClass:\"icon-bell-ringing-o\"})])]:_vm._e()],2),_vm._v(\" \"),_c('div',[(_vm.relationship.muting)?_c('button',{staticClass:\"btn btn-default btn-block toggled\",on:{\"click\":_vm.unmuteUser}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.muted'))+\"\\n \")]):_c('button',{staticClass:\"btn btn-default btn-block\",on:{\"click\":_vm.muteUser}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.mute'))+\"\\n \")])]),_vm._v(\" \"),_c('div',[_c('button',{staticClass:\"btn btn-default btn-block\",on:{\"click\":_vm.mentionUser}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('user_card.mention'))+\"\\n \")])]),_vm._v(\" \"),(_vm.loggedIn.role === \"admin\")?_c('ModerationTools',{attrs:{\"user\":_vm.user}}):_vm._e()],1):_vm._e(),_vm._v(\" \"),(!_vm.loggedIn && _vm.user.is_local)?_c('div',{staticClass:\"user-interactions\"},[_c('RemoteFollow',{attrs:{\"user\":_vm.user}})],1):_vm._e()])]),_vm._v(\" \"),(!_vm.hideBio)?_c('div',{staticClass:\"panel-body\"},[(!_vm.mergedConfig.hideUserStats && _vm.switcher)?_c('div',{staticClass:\"user-counts\"},[_c('div',{staticClass:\"user-count\",on:{\"click\":function($event){$event.preventDefault();return _vm.setProfileView('statuses')}}},[_c('h5',[_vm._v(_vm._s(_vm.$t('user_card.statuses')))]),_vm._v(\" \"),_c('span',[_vm._v(_vm._s(_vm.user.statuses_count)+\" \"),_c('br')])]),_vm._v(\" \"),_c('div',{staticClass:\"user-count\",on:{\"click\":function($event){$event.preventDefault();return _vm.setProfileView('friends')}}},[_c('h5',[_vm._v(_vm._s(_vm.$t('user_card.followees')))]),_vm._v(\" \"),_c('span',[_vm._v(_vm._s(_vm.hideFollowsCount ? _vm.$t('user_card.hidden') : _vm.user.friends_count))])]),_vm._v(\" \"),_c('div',{staticClass:\"user-count\",on:{\"click\":function($event){$event.preventDefault();return _vm.setProfileView('followers')}}},[_c('h5',[_vm._v(_vm._s(_vm.$t('user_card.followers')))]),_vm._v(\" \"),_c('span',[_vm._v(_vm._s(_vm.hideFollowersCount ? _vm.$t('user_card.hidden') : _vm.user.followers_count))])])]):_vm._e(),_vm._v(\" \"),(!_vm.hideBio && _vm.user.description_html)?_c('p',{staticClass:\"user-card-bio\",domProps:{\"innerHTML\":_vm._s(_vm.user.description_html)},on:{\"click\":function($event){$event.preventDefault();return _vm.linkClicked($event)}}}):(!_vm.hideBio)?_c('p',{staticClass:\"user-card-bio\"},[_vm._v(\"\\n \"+_vm._s(_vm.user.description)+\"\\n \")]):_vm._e()]):_vm._e()])}\nvar staticRenderFns = [function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"user-info-avatar-link-overlay\"},[_c('i',{staticClass:\"button-icon icon-zoom-in\"})])}]\nexport { render, staticRenderFns }","import StillImage from '../still-image/still-image.vue'\n\nconst UserAvatar = {\n props: [\n 'user',\n 'betterShadow',\n 'compact'\n ],\n data () {\n return {\n showPlaceholder: false\n }\n },\n components: {\n StillImage\n },\n computed: {\n imgSrc () {\n return this.showPlaceholder ? '/images/avi.png' : this.user.profile_image_url_original\n }\n },\n methods: {\n imageLoadError () {\n this.showPlaceholder = true\n }\n },\n watch: {\n src () {\n this.showPlaceholder = false\n }\n }\n}\n\nexport default UserAvatar\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./user_avatar.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./user_avatar.js\"\nimport __vue_script__ from \"!!babel-loader!./user_avatar.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-056a5e34\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./user_avatar.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('StillImage',{staticClass:\"avatar\",class:{ 'avatar-compact': _vm.compact, 'better-shadow': _vm.betterShadow },attrs:{\"alt\":_vm.user.screen_name,\"title\":_vm.user.screen_name,\"src\":_vm.imgSrc,\"image-load-error\":_vm.imageLoadError}})}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import { mapGetters } from 'vuex'\n\nconst FavoriteButton = {\n props: ['status', 'loggedIn'],\n data () {\n return {\n animated: false\n }\n },\n methods: {\n favorite () {\n if (!this.status.favorited) {\n this.$store.dispatch('favorite', { id: this.status.id })\n } else {\n this.$store.dispatch('unfavorite', { id: this.status.id })\n }\n this.animated = true\n setTimeout(() => {\n this.animated = false\n }, 500)\n }\n },\n computed: {\n classes () {\n return {\n 'icon-star-empty': !this.status.favorited,\n 'icon-star': this.status.favorited,\n 'animate-spin': this.animated\n }\n },\n ...mapGetters(['mergedConfig'])\n }\n}\n\nexport default FavoriteButton\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./favorite_button.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./favorite_button.js\"\nimport __vue_script__ from \"!!babel-loader!./favorite_button.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-2ced002f\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./favorite_button.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return (_vm.loggedIn)?_c('div',[_c('i',{staticClass:\"button-icon favorite-button fav-active\",class:_vm.classes,attrs:{\"title\":_vm.$t('tool_tip.favorite')},on:{\"click\":function($event){$event.preventDefault();return _vm.favorite()}}}),_vm._v(\" \"),(!_vm.mergedConfig.hidePostStats && _vm.status.fave_num > 0)?_c('span',[_vm._v(_vm._s(_vm.status.fave_num))]):_vm._e()]):_c('div',[_c('i',{staticClass:\"button-icon favorite-button\",class:_vm.classes,attrs:{\"title\":_vm.$t('tool_tip.favorite')}}),_vm._v(\" \"),(!_vm.mergedConfig.hidePostStats && _vm.status.fave_num > 0)?_c('span',[_vm._v(_vm._s(_vm.status.fave_num))]):_vm._e()])}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import Popover from '../popover/popover.vue'\nimport { mapGetters } from 'vuex'\n\nconst ReactButton = {\n props: ['status'],\n data () {\n return {\n filterWord: ''\n }\n },\n components: {\n Popover\n },\n methods: {\n addReaction (event, emoji, close) {\n const existingReaction = this.status.emoji_reactions.find(r => r.name === emoji)\n if (existingReaction && existingReaction.me) {\n this.$store.dispatch('unreactWithEmoji', { id: this.status.id, emoji })\n } else {\n this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji })\n }\n close()\n }\n },\n computed: {\n commonEmojis () {\n return ['❤️', '😠', '👀', '😂', '🔥']\n },\n emojis () {\n if (this.filterWord !== '') {\n return this.$store.state.instance.emoji.filter(emoji => emoji.displayText.includes(this.filterWord))\n }\n return this.$store.state.instance.emoji || []\n },\n ...mapGetters(['mergedConfig'])\n }\n}\n\nexport default ReactButton\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./react_button.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./react_button.js\"\nimport __vue_script__ from \"!!babel-loader!./react_button.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-185f65eb\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./react_button.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('Popover',{staticClass:\"react-button-popover\",attrs:{\"trigger\":\"click\",\"placement\":\"top\",\"offset\":{ y: 5 }},scopedSlots:_vm._u([{key:\"content\",fn:function(ref){\nvar close = ref.close;\nreturn _c('div',{},[_c('div',{staticClass:\"reaction-picker-filter\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.filterWord),expression:\"filterWord\"}],attrs:{\"placeholder\":_vm.$t('emoji.search_emoji')},domProps:{\"value\":(_vm.filterWord)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.filterWord=$event.target.value}}})]),_vm._v(\" \"),_c('div',{staticClass:\"reaction-picker\"},[_vm._l((_vm.commonEmojis),function(emoji){return _c('span',{key:emoji,staticClass:\"emoji-button\",on:{\"click\":function($event){return _vm.addReaction($event, emoji, close)}}},[_vm._v(\"\\n \"+_vm._s(emoji)+\"\\n \")])}),_vm._v(\" \"),_c('div',{staticClass:\"reaction-picker-divider\"}),_vm._v(\" \"),_vm._l((_vm.emojis),function(emoji,key){return _c('span',{key:key,staticClass:\"emoji-button\",on:{\"click\":function($event){return _vm.addReaction($event, emoji.replacement, close)}}},[_vm._v(\"\\n \"+_vm._s(emoji.replacement)+\"\\n \")])}),_vm._v(\" \"),_c('div',{staticClass:\"reaction-bottom-fader\"})],2)])}}])},[_vm._v(\" \"),_c('i',{staticClass:\"icon-smile button-icon add-reaction-button\",attrs:{\"slot\":\"trigger\",\"title\":_vm.$t('tool_tip.add_reaction')},slot:\"trigger\"})])}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import { mapGetters } from 'vuex'\n\nconst RetweetButton = {\n props: ['status', 'loggedIn', 'visibility'],\n data () {\n return {\n animated: false\n }\n },\n methods: {\n retweet () {\n if (!this.status.repeated) {\n this.$store.dispatch('retweet', { id: this.status.id })\n } else {\n this.$store.dispatch('unretweet', { id: this.status.id })\n }\n this.animated = true\n setTimeout(() => {\n this.animated = false\n }, 500)\n }\n },\n computed: {\n classes () {\n return {\n 'retweeted': this.status.repeated,\n 'retweeted-empty': !this.status.repeated,\n 'animate-spin': this.animated\n }\n },\n ...mapGetters(['mergedConfig'])\n }\n}\n\nexport default RetweetButton\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./retweet_button.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./retweet_button.js\"\nimport __vue_script__ from \"!!babel-loader!./retweet_button.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-538410cc\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./retweet_button.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return (_vm.loggedIn)?_c('div',[(_vm.visibility !== 'private' && _vm.visibility !== 'direct')?[_c('i',{staticClass:\"button-icon retweet-button icon-retweet rt-active\",class:_vm.classes,attrs:{\"title\":_vm.$t('tool_tip.repeat')},on:{\"click\":function($event){$event.preventDefault();return _vm.retweet()}}}),_vm._v(\" \"),(!_vm.mergedConfig.hidePostStats && _vm.status.repeat_num > 0)?_c('span',[_vm._v(_vm._s(_vm.status.repeat_num))]):_vm._e()]:[_c('i',{staticClass:\"button-icon icon-lock\",class:_vm.classes,attrs:{\"title\":_vm.$t('timeline.no_retweet_hint')}})]],2):(!_vm.loggedIn)?_c('div',[_c('i',{staticClass:\"button-icon icon-retweet\",class:_vm.classes,attrs:{\"title\":_vm.$t('tool_tip.repeat')}}),_vm._v(\" \"),(!_vm.mergedConfig.hidePostStats && _vm.status.repeat_num > 0)?_c('span',[_vm._v(_vm._s(_vm.status.repeat_num))]):_vm._e()]):_vm._e()}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import Popover from '../popover/popover.vue'\n\nconst ExtraButtons = {\n props: [ 'status' ],\n components: { Popover },\n methods: {\n deleteStatus () {\n const confirmed = window.confirm(this.$t('status.delete_confirm'))\n if (confirmed) {\n this.$store.dispatch('deleteStatus', { id: this.status.id })\n }\n },\n pinStatus () {\n this.$store.dispatch('pinStatus', this.status.id)\n .then(() => this.$emit('onSuccess'))\n .catch(err => this.$emit('onError', err.error.error))\n },\n unpinStatus () {\n this.$store.dispatch('unpinStatus', this.status.id)\n .then(() => this.$emit('onSuccess'))\n .catch(err => this.$emit('onError', err.error.error))\n },\n muteConversation () {\n this.$store.dispatch('muteConversation', this.status.id)\n .then(() => this.$emit('onSuccess'))\n .catch(err => this.$emit('onError', err.error.error))\n },\n unmuteConversation () {\n this.$store.dispatch('unmuteConversation', this.status.id)\n .then(() => this.$emit('onSuccess'))\n .catch(err => this.$emit('onError', err.error.error))\n },\n copyLink () {\n navigator.clipboard.writeText(this.statusLink)\n .then(() => this.$emit('onSuccess'))\n .catch(err => this.$emit('onError', err.error.error))\n }\n },\n computed: {\n currentUser () { return this.$store.state.users.currentUser },\n canDelete () {\n if (!this.currentUser) { return }\n const superuser = this.currentUser.rights.moderator || this.currentUser.rights.admin\n return superuser || this.status.user.id === this.currentUser.id\n },\n ownStatus () {\n return this.status.user.id === this.currentUser.id\n },\n canPin () {\n return this.ownStatus && (this.status.visibility === 'public' || this.status.visibility === 'unlisted')\n },\n canMute () {\n return !!this.currentUser\n },\n statusLink () {\n return `${this.$store.state.instance.server}${this.$router.resolve({ name: 'conversation', params: { id: this.status.id } }).href}`\n }\n }\n}\n\nexport default ExtraButtons\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./extra_buttons.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./extra_buttons.js\"\nimport __vue_script__ from \"!!babel-loader!./extra_buttons.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-b30b8de6\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./extra_buttons.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('Popover',{staticClass:\"extra-button-popover\",attrs:{\"trigger\":\"click\",\"placement\":\"top\"},scopedSlots:_vm._u([{key:\"content\",fn:function(ref){\nvar close = ref.close;\nreturn _c('div',{},[_c('div',{staticClass:\"dropdown-menu\"},[(_vm.canMute && !_vm.status.thread_muted)?_c('button',{staticClass:\"dropdown-item dropdown-item-icon\",on:{\"click\":function($event){$event.preventDefault();return _vm.muteConversation($event)}}},[_c('i',{staticClass:\"icon-eye-off\"}),_c('span',[_vm._v(_vm._s(_vm.$t(\"status.mute_conversation\")))])]):_vm._e(),_vm._v(\" \"),(_vm.canMute && _vm.status.thread_muted)?_c('button',{staticClass:\"dropdown-item dropdown-item-icon\",on:{\"click\":function($event){$event.preventDefault();return _vm.unmuteConversation($event)}}},[_c('i',{staticClass:\"icon-eye-off\"}),_c('span',[_vm._v(_vm._s(_vm.$t(\"status.unmute_conversation\")))])]):_vm._e(),_vm._v(\" \"),(!_vm.status.pinned && _vm.canPin)?_c('button',{staticClass:\"dropdown-item dropdown-item-icon\",on:{\"click\":[function($event){$event.preventDefault();return _vm.pinStatus($event)},close]}},[_c('i',{staticClass:\"icon-pin\"}),_c('span',[_vm._v(_vm._s(_vm.$t(\"status.pin\")))])]):_vm._e(),_vm._v(\" \"),(_vm.status.pinned && _vm.canPin)?_c('button',{staticClass:\"dropdown-item dropdown-item-icon\",on:{\"click\":[function($event){$event.preventDefault();return _vm.unpinStatus($event)},close]}},[_c('i',{staticClass:\"icon-pin\"}),_c('span',[_vm._v(_vm._s(_vm.$t(\"status.unpin\")))])]):_vm._e(),_vm._v(\" \"),(_vm.canDelete)?_c('button',{staticClass:\"dropdown-item dropdown-item-icon\",on:{\"click\":[function($event){$event.preventDefault();return _vm.deleteStatus($event)},close]}},[_c('i',{staticClass:\"icon-cancel\"}),_c('span',[_vm._v(_vm._s(_vm.$t(\"status.delete\")))])]):_vm._e(),_vm._v(\" \"),_c('button',{staticClass:\"dropdown-item dropdown-item-icon\",on:{\"click\":[function($event){$event.preventDefault();return _vm.copyLink($event)},close]}},[_c('i',{staticClass:\"icon-share\"}),_c('span',[_vm._v(_vm._s(_vm.$t(\"status.copy_link\")))])])])])}}])},[_vm._v(\" \"),_c('i',{staticClass:\"icon-ellipsis button-icon\",attrs:{\"slot\":\"trigger\"},slot:\"trigger\"})])}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import UserAvatar from '../user_avatar/user_avatar.vue'\nimport generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'\n\nconst AvatarList = {\n props: ['users'],\n computed: {\n slicedUsers () {\n return this.users ? this.users.slice(0, 15) : []\n }\n },\n components: {\n UserAvatar\n },\n methods: {\n userProfileLink (user) {\n return generateProfileLink(user.id, user.screen_name, this.$store.state.instance.restrictedNicknames)\n }\n }\n}\n\nexport default AvatarList\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./avatar_list.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./avatar_list.js\"\nimport __vue_script__ from \"!!babel-loader!./avatar_list.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-4cea5bcf\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./avatar_list.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"avatars\"},_vm._l((_vm.slicedUsers),function(user){return _c('router-link',{key:user.id,staticClass:\"avatars-item\",attrs:{\"to\":_vm.userProfileLink(user)}},[_c('UserAvatar',{staticClass:\"avatar-small\",attrs:{\"user\":user}})],1)}),1)}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import StillImage from '../still-image/still-image.vue'\nimport VideoAttachment from '../video_attachment/video_attachment.vue'\nimport nsfwImage from '../../assets/nsfw.png'\nimport fileTypeService from '../../services/file_type/file_type.service.js'\nimport { mapGetters } from 'vuex'\n\nconst Attachment = {\n props: [\n 'attachment',\n 'nsfw',\n 'statusId',\n 'size',\n 'allowPlay',\n 'setMedia',\n 'naturalSizeLoad'\n ],\n data () {\n return {\n nsfwImage: this.$store.state.instance.nsfwCensorImage || nsfwImage,\n hideNsfwLocal: this.$store.getters.mergedConfig.hideNsfw,\n preloadImage: this.$store.getters.mergedConfig.preloadImage,\n loading: false,\n img: fileTypeService.fileType(this.attachment.mimetype) === 'image' && document.createElement('img'),\n modalOpen: false,\n showHidden: false\n }\n },\n components: {\n StillImage,\n VideoAttachment\n },\n computed: {\n usePlaceHolder () {\n return this.size === 'hide' || this.type === 'unknown'\n },\n referrerpolicy () {\n return this.$store.state.instance.mediaProxyAvailable ? '' : 'no-referrer'\n },\n type () {\n return fileTypeService.fileType(this.attachment.mimetype)\n },\n hidden () {\n return this.nsfw && this.hideNsfwLocal && !this.showHidden\n },\n isEmpty () {\n return (this.type === 'html' && !this.attachment.oembed) || this.type === 'unknown'\n },\n isSmall () {\n return this.size === 'small'\n },\n fullwidth () {\n return this.type === 'html' || this.type === 'audio'\n },\n ...mapGetters(['mergedConfig'])\n },\n methods: {\n linkClicked ({ target }) {\n if (target.tagName === 'A') {\n window.open(target.href, '_blank')\n }\n },\n openModal (event) {\n const modalTypes = this.mergedConfig.playVideosInModal\n ? ['image', 'video']\n : ['image']\n if (fileTypeService.fileMatchesSomeType(modalTypes, this.attachment) ||\n this.usePlaceHolder\n ) {\n event.stopPropagation()\n event.preventDefault()\n this.setMedia()\n this.$store.dispatch('setCurrent', this.attachment)\n }\n },\n toggleHidden (event) {\n if (\n (this.mergedConfig.useOneClickNsfw && !this.showHidden) &&\n (this.type !== 'video' || this.mergedConfig.playVideosInModal)\n ) {\n this.openModal(event)\n return\n }\n if (this.img && !this.preloadImage) {\n if (this.img.onload) {\n this.img.onload()\n } else {\n this.loading = true\n this.img.src = this.attachment.url\n this.img.onload = () => {\n this.loading = false\n this.showHidden = !this.showHidden\n }\n }\n } else {\n this.showHidden = !this.showHidden\n }\n },\n onImageLoad (image) {\n const width = image.naturalWidth\n const height = image.naturalHeight\n this.naturalSizeLoad && this.naturalSizeLoad({ width, height })\n }\n }\n}\n\nexport default Attachment\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./attachment.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./attachment.js\"\nimport __vue_script__ from \"!!babel-loader!./attachment.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-61e0eb0c\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./attachment.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {\nvar _obj;\nvar _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return (_vm.usePlaceHolder)?_c('div',{on:{\"click\":_vm.openModal}},[(_vm.type !== 'html')?_c('a',{staticClass:\"placeholder\",attrs:{\"target\":\"_blank\",\"href\":_vm.attachment.url}},[_vm._v(\"\\n [\"+_vm._s(_vm.nsfw ? \"NSFW/\" : \"\")+_vm._s(_vm.type.toUpperCase())+\"]\\n \")]):_vm._e()]):_c('div',{directives:[{name:\"show\",rawName:\"v-show\",value:(!_vm.isEmpty),expression:\"!isEmpty\"}],staticClass:\"attachment\",class:( _obj = {}, _obj[_vm.type] = true, _obj.loading = _vm.loading, _obj['fullwidth'] = _vm.fullwidth, _obj['nsfw-placeholder'] = _vm.hidden, _obj )},[(_vm.hidden)?_c('a',{staticClass:\"image-attachment\",attrs:{\"href\":_vm.attachment.url},on:{\"click\":function($event){$event.preventDefault();return _vm.toggleHidden($event)}}},[_c('img',{key:_vm.nsfwImage,staticClass:\"nsfw\",class:{'small': _vm.isSmall},attrs:{\"src\":_vm.nsfwImage}}),_vm._v(\" \"),(_vm.type === 'video')?_c('i',{staticClass:\"play-icon icon-play-circled\"}):_vm._e()]):_vm._e(),_vm._v(\" \"),(_vm.nsfw && _vm.hideNsfwLocal && !_vm.hidden)?_c('div',{staticClass:\"hider\"},[_c('a',{attrs:{\"href\":\"#\"},on:{\"click\":function($event){$event.preventDefault();return _vm.toggleHidden($event)}}},[_vm._v(\"Hide\")])]):_vm._e(),_vm._v(\" \"),(_vm.type === 'image' && (!_vm.hidden || _vm.preloadImage))?_c('a',{staticClass:\"image-attachment\",class:{'hidden': _vm.hidden && _vm.preloadImage },attrs:{\"href\":_vm.attachment.url,\"target\":\"_blank\",\"title\":_vm.attachment.description},on:{\"click\":_vm.openModal}},[_c('StillImage',{attrs:{\"referrerpolicy\":_vm.referrerpolicy,\"mimetype\":_vm.attachment.mimetype,\"src\":_vm.attachment.large_thumb_url || _vm.attachment.url,\"image-load-handler\":_vm.onImageLoad}})],1):_vm._e(),_vm._v(\" \"),(_vm.type === 'video' && !_vm.hidden)?_c('a',{staticClass:\"video-container\",class:{'small': _vm.isSmall},attrs:{\"href\":_vm.allowPlay ? undefined : _vm.attachment.url},on:{\"click\":_vm.openModal}},[_c('VideoAttachment',{staticClass:\"video\",attrs:{\"attachment\":_vm.attachment,\"controls\":_vm.allowPlay}}),_vm._v(\" \"),(!_vm.allowPlay)?_c('i',{staticClass:\"play-icon icon-play-circled\"}):_vm._e()],1):_vm._e(),_vm._v(\" \"),(_vm.type === 'audio')?_c('audio',{attrs:{\"src\":_vm.attachment.url,\"controls\":\"\"}}):_vm._e(),_vm._v(\" \"),(_vm.type === 'html' && _vm.attachment.oembed)?_c('div',{staticClass:\"oembed\",on:{\"click\":function($event){$event.preventDefault();return _vm.linkClicked($event)}}},[(_vm.attachment.thumb_url)?_c('div',{staticClass:\"image\"},[_c('img',{attrs:{\"src\":_vm.attachment.thumb_url}})]):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"text\"},[_c('h1',[_c('a',{attrs:{\"href\":_vm.attachment.url}},[_vm._v(_vm._s(_vm.attachment.oembed.title))])]),_vm._v(\" \"),_c('div',{domProps:{\"innerHTML\":_vm._s(_vm.attachment.oembed.oembedHTML)}})])]):_vm._e()])}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import Timeago from '../timeago/timeago.vue'\nimport { forEach, map } from 'lodash'\n\nexport default {\n name: 'Poll',\n props: ['basePoll'],\n components: { Timeago },\n data () {\n return {\n loading: false,\n choices: []\n }\n },\n created () {\n if (!this.$store.state.polls.pollsObject[this.pollId]) {\n this.$store.dispatch('mergeOrAddPoll', this.basePoll)\n }\n this.$store.dispatch('trackPoll', this.pollId)\n },\n destroyed () {\n this.$store.dispatch('untrackPoll', this.pollId)\n },\n computed: {\n pollId () {\n return this.basePoll.id\n },\n poll () {\n const storePoll = this.$store.state.polls.pollsObject[this.pollId]\n return storePoll || {}\n },\n options () {\n return (this.poll && this.poll.options) || []\n },\n expiresAt () {\n return (this.poll && this.poll.expires_at) || 0\n },\n expired () {\n return (this.poll && this.poll.expired) || false\n },\n loggedIn () {\n return this.$store.state.users.currentUser\n },\n showResults () {\n return this.poll.voted || this.expired || !this.loggedIn\n },\n totalVotesCount () {\n return this.poll.votes_count\n },\n containerClass () {\n return {\n loading: this.loading\n }\n },\n choiceIndices () {\n // Convert array of booleans into an array of indices of the\n // items that were 'true', so [true, false, false, true] becomes\n // [0, 3].\n return this.choices\n .map((entry, index) => entry && index)\n .filter(value => typeof value === 'number')\n },\n isDisabled () {\n const noChoice = this.choiceIndices.length === 0\n return this.loading || noChoice\n }\n },\n methods: {\n percentageForOption (count) {\n return this.totalVotesCount === 0 ? 0 : Math.round(count / this.totalVotesCount * 100)\n },\n resultTitle (option) {\n return `${option.votes_count}/${this.totalVotesCount} ${this.$t('polls.votes')}`\n },\n fetchPoll () {\n this.$store.dispatch('refreshPoll', { id: this.statusId, pollId: this.poll.id })\n },\n activateOption (index) {\n // forgive me father: doing checking the radio/checkboxes\n // in code because of customized input elements need either\n // a) an extra element for the actual graphic, or b) use a\n // pseudo element for the label. We use b) which mandates\n // using \"for\" and \"id\" matching which isn't nice when the\n // same poll appears multiple times on the site (notifs and\n // timeline for example). With code we can make sure it just\n // works without altering the pseudo element implementation.\n const allElements = this.$el.querySelectorAll('input')\n const clickedElement = this.$el.querySelector(`input[value=\"${index}\"]`)\n if (this.poll.multiple) {\n // Checkboxes, toggle only the clicked one\n clickedElement.checked = !clickedElement.checked\n } else {\n // Radio button, uncheck everything and check the clicked one\n forEach(allElements, element => { element.checked = false })\n clickedElement.checked = true\n }\n this.choices = map(allElements, e => e.checked)\n },\n optionId (index) {\n return `poll${this.poll.id}-${index}`\n },\n vote () {\n if (this.choiceIndices.length === 0) return\n this.loading = true\n this.$store.dispatch(\n 'votePoll',\n { id: this.statusId, pollId: this.poll.id, choices: this.choiceIndices }\n ).then(poll => {\n this.loading = false\n })\n }\n }\n}\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./poll.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./poll.js\"\nimport __vue_script__ from \"!!babel-loader!./poll.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-db51c57e\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./poll.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"poll\",class:_vm.containerClass},[_vm._l((_vm.options),function(option,index){return _c('div',{key:index,staticClass:\"poll-option\"},[(_vm.showResults)?_c('div',{staticClass:\"option-result\",attrs:{\"title\":_vm.resultTitle(option)}},[_c('div',{staticClass:\"option-result-label\"},[_c('span',{staticClass:\"result-percentage\"},[_vm._v(\"\\n \"+_vm._s(_vm.percentageForOption(option.votes_count))+\"%\\n \")]),_vm._v(\" \"),_c('span',[_vm._v(_vm._s(option.title))])]),_vm._v(\" \"),_c('div',{staticClass:\"result-fill\",style:({ 'width': ((_vm.percentageForOption(option.votes_count)) + \"%\") })})]):_c('div',{on:{\"click\":function($event){return _vm.activateOption(index)}}},[(_vm.poll.multiple)?_c('input',{attrs:{\"type\":\"checkbox\",\"disabled\":_vm.loading},domProps:{\"value\":index}}):_c('input',{attrs:{\"type\":\"radio\",\"disabled\":_vm.loading},domProps:{\"value\":index}}),_vm._v(\" \"),_c('label',{staticClass:\"option-vote\"},[_c('div',[_vm._v(_vm._s(option.title))])])])])}),_vm._v(\" \"),_c('div',{staticClass:\"footer faint\"},[(!_vm.showResults)?_c('button',{staticClass:\"btn btn-default poll-vote-button\",attrs:{\"type\":\"button\",\"disabled\":_vm.isDisabled},on:{\"click\":_vm.vote}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('polls.vote'))+\"\\n \")]):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"total\"},[_vm._v(\"\\n \"+_vm._s(_vm.totalVotesCount)+\" \"+_vm._s(_vm.$t(\"polls.votes\"))+\" · \\n \")]),_vm._v(\" \"),_c('i18n',{attrs:{\"path\":_vm.expired ? 'polls.expired' : 'polls.expires_in'}},[_c('Timeago',{attrs:{\"time\":_vm.expiresAt,\"auto-update\":60,\"now-threshold\":0}})],1)],1)],2)}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import Attachment from '../attachment/attachment.vue'\nimport { chunk, last, dropRight, sumBy } from 'lodash'\n\nconst Gallery = {\n props: [\n 'attachments',\n 'nsfw',\n 'setMedia'\n ],\n data () {\n return {\n sizes: {}\n }\n },\n components: { Attachment },\n computed: {\n rows () {\n if (!this.attachments) {\n return []\n }\n const rows = chunk(this.attachments, 3)\n if (last(rows).length === 1 && rows.length > 1) {\n // if 1 attachment on last row -> add it to the previous row instead\n const lastAttachment = last(rows)[0]\n const allButLastRow = dropRight(rows)\n last(allButLastRow).push(lastAttachment)\n return allButLastRow\n }\n return rows\n },\n useContainFit () {\n return this.$store.getters.mergedConfig.useContainFit\n }\n },\n methods: {\n onNaturalSizeLoad (id, size) {\n this.$set(this.sizes, id, size)\n },\n rowStyle (itemsPerRow) {\n return { 'padding-bottom': `${(100 / (itemsPerRow + 0.6))}%` }\n },\n itemStyle (id, row) {\n const total = sumBy(row, item => this.getAspectRatio(item.id))\n return { flex: `${this.getAspectRatio(id) / total} 1 0%` }\n },\n getAspectRatio (id) {\n const size = this.sizes[id]\n return size ? size.width / size.height : 1\n }\n }\n}\n\nexport default Gallery\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./gallery.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./gallery.js\"\nimport __vue_script__ from \"!!babel-loader!./gallery.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-68a574b8\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./gallery.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{ref:\"galleryContainer\",staticStyle:{\"width\":\"100%\"}},_vm._l((_vm.rows),function(row,index){return _c('div',{key:index,staticClass:\"gallery-row\",class:{ 'contain-fit': _vm.useContainFit, 'cover-fit': !_vm.useContainFit },style:(_vm.rowStyle(row.length))},[_c('div',{staticClass:\"gallery-row-inner\"},_vm._l((row),function(attachment){return _c('attachment',{key:attachment.id,style:(_vm.itemStyle(attachment.id, row)),attrs:{\"set-media\":_vm.setMedia,\"nsfw\":_vm.nsfw,\"attachment\":attachment,\"allow-play\":false,\"natural-size-load\":_vm.onNaturalSizeLoad.bind(null, attachment.id)}})}),1)])}),0)}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","const LinkPreview = {\n name: 'LinkPreview',\n props: [\n 'card',\n 'size',\n 'nsfw'\n ],\n data () {\n return {\n imageLoaded: false\n }\n },\n computed: {\n useImage () {\n // Currently BE shoudn't give cards if tagged NSFW, this is a bit paranoid\n // as it makes sure to hide the image if somehow NSFW tagged preview can\n // exist.\n return this.card.image && !this.nsfw && this.size !== 'hide'\n },\n useDescription () {\n return this.card.description && /\\S/.test(this.card.description)\n }\n },\n created () {\n if (this.useImage) {\n const newImg = new Image()\n newImg.onload = () => {\n this.imageLoaded = true\n }\n newImg.src = this.card.image\n }\n }\n}\n\nexport default LinkPreview\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./link-preview.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./link-preview.js\"\nimport __vue_script__ from \"!!babel-loader!./link-preview.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-7c8d99ac\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./link-preview.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',[_c('a',{staticClass:\"link-preview-card\",attrs:{\"href\":_vm.card.url,\"target\":\"_blank\",\"rel\":\"noopener\"}},[(_vm.useImage && _vm.imageLoaded)?_c('div',{staticClass:\"card-image\",class:{ 'small-image': _vm.size === 'small' }},[_c('img',{attrs:{\"src\":_vm.card.image}})]):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"card-content\"},[_c('span',{staticClass:\"card-host faint\"},[_vm._v(_vm._s(_vm.card.provider_name))]),_vm._v(\" \"),_c('h4',{staticClass:\"card-title\"},[_vm._v(_vm._s(_vm.card.title))]),_vm._v(\" \"),(_vm.useDescription)?_c('p',{staticClass:\"card-description\"},[_vm._v(_vm._s(_vm.card.description))]):_vm._e()])])])}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import Attachment from '../attachment/attachment.vue'\nimport Poll from '../poll/poll.vue'\nimport Gallery from '../gallery/gallery.vue'\nimport LinkPreview from '../link-preview/link-preview.vue'\nimport generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'\nimport fileType from 'src/services/file_type/file_type.service'\nimport { processHtml } from 'src/services/tiny_post_html_processor/tiny_post_html_processor.service.js'\nimport { mentionMatchesUrl, extractTagFromUrl } from 'src/services/matcher/matcher.service.js'\nimport { mapGetters, mapState } from 'vuex'\n\nconst StatusContent = {\n name: 'StatusContent',\n props: [\n 'status',\n 'focused',\n 'noHeading',\n 'fullContent'\n ],\n data () {\n return {\n showingTall: this.inConversation && this.focused,\n showingLongSubject: false,\n // not as computed because it sets the initial state which will be changed later\n expandingSubject: !this.$store.getters.mergedConfig.collapseMessageWithSubject\n }\n },\n computed: {\n localCollapseSubjectDefault () {\n return this.mergedConfig.collapseMessageWithSubject\n },\n hideAttachments () {\n return (this.mergedConfig.hideAttachments && !this.inConversation) ||\n (this.mergedConfig.hideAttachmentsInConv && this.inConversation)\n },\n // This is a bit hacky, but we want to approximate post height before rendering\n // so we count newlines (masto uses

for paragraphs, GS uses
between them)\n // as well as approximate line count by counting characters and approximating ~80\n // per line.\n //\n // Using max-height + overflow: auto for status components resulted in false positives\n // very often with japanese characters, and it was very annoying.\n tallStatus () {\n const lengthScore = this.status.statusnet_html.split(/ 20\n },\n longSubject () {\n return this.status.summary.length > 900\n },\n // When a status has a subject and is also tall, we should only have one show more/less button. If the default is to collapse statuses with subjects, we just treat it like a status with a subject; otherwise, we just treat it like a tall status.\n mightHideBecauseSubject () {\n return this.status.summary && (!this.tallStatus || this.localCollapseSubjectDefault)\n },\n mightHideBecauseTall () {\n return this.tallStatus && (!this.status.summary || !this.localCollapseSubjectDefault)\n },\n hideSubjectStatus () {\n return this.mightHideBecauseSubject && !this.expandingSubject\n },\n hideTallStatus () {\n return this.mightHideBecauseTall && !this.showingTall\n },\n showingMore () {\n return (this.mightHideBecauseTall && this.showingTall) || (this.mightHideBecauseSubject && this.expandingSubject)\n },\n nsfwClickthrough () {\n if (!this.status.nsfw) {\n return false\n }\n if (this.status.summary && this.localCollapseSubjectDefault) {\n return false\n }\n return true\n },\n attachmentSize () {\n if ((this.mergedConfig.hideAttachments && !this.inConversation) ||\n (this.mergedConfig.hideAttachmentsInConv && this.inConversation) ||\n (this.status.attachments.length > this.maxThumbnails)) {\n return 'hide'\n } else if (this.compact) {\n return 'small'\n }\n return 'normal'\n },\n galleryTypes () {\n if (this.attachmentSize === 'hide') {\n return []\n }\n return this.mergedConfig.playVideosInModal\n ? ['image', 'video']\n : ['image']\n },\n galleryAttachments () {\n return this.status.attachments.filter(\n file => fileType.fileMatchesSomeType(this.galleryTypes, file)\n )\n },\n nonGalleryAttachments () {\n return this.status.attachments.filter(\n file => !fileType.fileMatchesSomeType(this.galleryTypes, file)\n )\n },\n hasImageAttachments () {\n return this.status.attachments.some(\n file => fileType.fileType(file.mimetype) === 'image'\n )\n },\n hasVideoAttachments () {\n return this.status.attachments.some(\n file => fileType.fileType(file.mimetype) === 'video'\n )\n },\n maxThumbnails () {\n return this.mergedConfig.maxThumbnails\n },\n postBodyHtml () {\n const html = this.status.statusnet_html\n\n if (this.mergedConfig.greentext) {\n try {\n if (html.includes('>')) {\n // This checks if post has '>' at the beginning, excluding mentions so that @mention >impying works\n return processHtml(html, (string) => {\n if (string.includes('>') &&\n string\n .replace(/<[^>]+?>/gi, '') // remove all tags\n .replace(/@\\w+/gi, '') // remove mentions (even failed ones)\n .trim()\n .startsWith('>')) {\n return `${string}`\n } else {\n return string\n }\n })\n } else {\n return html\n }\n } catch (e) {\n console.err('Failed to process status html', e)\n return html\n }\n } else {\n return html\n }\n },\n contentHtml () {\n if (!this.status.summary_html) {\n return this.postBodyHtml\n }\n return this.status.summary_html + '
' + this.postBodyHtml\n },\n ...mapGetters(['mergedConfig']),\n ...mapState({\n betterShadow: state => state.interface.browserSupport.cssFilter,\n currentUser: state => state.users.currentUser\n })\n },\n components: {\n Attachment,\n Poll,\n Gallery,\n LinkPreview\n },\n methods: {\n linkClicked (event) {\n const target = event.target.closest('.status-content a')\n if (target) {\n if (target.className.match(/mention/)) {\n const href = target.href\n const attn = this.status.attentions.find(attn => mentionMatchesUrl(attn, href))\n if (attn) {\n event.stopPropagation()\n event.preventDefault()\n const link = this.generateUserProfileLink(attn.id, attn.screen_name)\n this.$router.push(link)\n return\n }\n }\n if (target.rel.match(/(?:^|\\s)tag(?:$|\\s)/) || target.className.match(/hashtag/)) {\n // Extract tag name from link url\n const tag = extractTagFromUrl(target.href)\n if (tag) {\n const link = this.generateTagLink(tag)\n this.$router.push(link)\n return\n }\n }\n window.open(target.href, '_blank')\n }\n },\n toggleShowMore () {\n if (this.mightHideBecauseTall) {\n this.showingTall = !this.showingTall\n } else if (this.mightHideBecauseSubject) {\n this.expandingSubject = !this.expandingSubject\n }\n },\n generateUserProfileLink (id, name) {\n return generateProfileLink(id, name, this.$store.state.instance.restrictedNicknames)\n },\n generateTagLink (tag) {\n return `/tag/${tag}`\n },\n setMedia () {\n const attachments = this.attachmentSize === 'hide' ? this.status.attachments : this.galleryAttachments\n return () => this.$store.dispatch('setMedia', attachments)\n }\n }\n}\n\nexport default StatusContent\n","/**\n * This is a tiny purpose-built HTML parser/processor. This basically detects any type of visual newline and\n * allows it to be processed, useful for greentexting, mostly\n *\n * known issue: doesn't handle CDATA so nested CDATA might not work well\n *\n * @param {Object} input - input data\n * @param {(string) => string} processor - function that will be called on every line\n * @return {string} processed html\n */\nexport const processHtml = (html, processor) => {\n const handledTags = new Set(['p', 'br', 'div'])\n const openCloseTags = new Set(['p', 'div'])\n\n let buffer = '' // Current output buffer\n const level = [] // How deep we are in tags and which tags were there\n let textBuffer = '' // Current line content\n let tagBuffer = null // Current tag buffer, if null = we are not currently reading a tag\n\n // Extracts tag name from tag, i.e. => span\n const getTagName = (tag) => {\n const result = /(?:<\\/(\\w+)>|<(\\w+)\\s?[^/]*?\\/?>)/gi.exec(tag)\n return result && (result[1] || result[2])\n }\n\n const flush = () => { // Processes current line buffer, adds it to output buffer and clears line buffer\n if (textBuffer.trim().length > 0) {\n buffer += processor(textBuffer)\n } else {\n buffer += textBuffer\n }\n textBuffer = ''\n }\n\n const handleBr = (tag) => { // handles single newlines/linebreaks/selfclosing\n flush()\n buffer += tag\n }\n\n const handleOpen = (tag) => { // handles opening tags\n flush()\n buffer += tag\n level.push(tag)\n }\n\n const handleClose = (tag) => { // handles closing tags\n flush()\n buffer += tag\n if (level[level.length - 1] === tag) {\n level.pop()\n }\n }\n\n for (let i = 0; i < html.length; i++) {\n const char = html[i]\n if (char === '<' && tagBuffer === null) {\n tagBuffer = char\n } else if (char !== '>' && tagBuffer !== null) {\n tagBuffer += char\n } else if (char === '>' && tagBuffer !== null) {\n tagBuffer += char\n const tagFull = tagBuffer\n tagBuffer = null\n const tagName = getTagName(tagFull)\n if (handledTags.has(tagName)) {\n if (tagName === 'br') {\n handleBr(tagFull)\n } else if (openCloseTags.has(tagName)) {\n if (tagFull[1] === '/') {\n handleClose(tagFull)\n } else if (tagFull[tagFull.length - 2] === '/') {\n // self-closing\n handleBr(tagFull)\n } else {\n handleOpen(tagFull)\n }\n }\n } else {\n textBuffer += tagFull\n }\n } else if (char === '\\n') {\n handleBr(char)\n } else {\n textBuffer += char\n }\n }\n if (tagBuffer) {\n textBuffer += tagBuffer\n }\n\n flush()\n\n return buffer\n}\n","export const mentionMatchesUrl = (attention, url) => {\n if (url === attention.statusnet_profile_url) {\n return true\n }\n const [namepart, instancepart] = attention.screen_name.split('@')\n const matchstring = new RegExp('://' + instancepart + '/.*' + namepart + '$', 'g')\n\n return !!url.match(matchstring)\n}\n\n/**\n * Extract tag name from pleroma or mastodon url.\n * i.e https://bikeshed.party/tag/photo or https://quey.org/tags/sky\n * @param {string} url\n */\nexport const extractTagFromUrl = (url) => {\n const regex = /tag[s]*\\/(\\w+)$/g\n const result = regex.exec(url)\n if (!result) {\n return false\n }\n return result[1]\n}\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./status_content.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./status_content.js\"\nimport __vue_script__ from \"!!babel-loader!./status_content.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-43c5cfd4\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./status_content.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"status-body\"},[_vm._t(\"header\"),_vm._v(\" \"),(_vm.longSubject)?_c('div',{staticClass:\"status-content-wrapper\",class:{ 'tall-status': !_vm.showingLongSubject }},[(!_vm.showingLongSubject)?_c('a',{staticClass:\"tall-status-hider\",class:{ 'tall-status-hider_focused': _vm.focused },attrs:{\"href\":\"#\"},on:{\"click\":function($event){$event.preventDefault();_vm.showingLongSubject=true}}},[_vm._v(\"\\n \"+_vm._s(_vm.$t(\"general.show_more\"))+\"\\n \"),(_vm.hasImageAttachments)?_c('span',{staticClass:\"icon-picture\"}):_vm._e(),_vm._v(\" \"),(_vm.hasVideoAttachments)?_c('span',{staticClass:\"icon-video\"}):_vm._e(),_vm._v(\" \"),(_vm.status.card)?_c('span',{staticClass:\"icon-link\"}):_vm._e()]):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"status-content media-body\",domProps:{\"innerHTML\":_vm._s(_vm.contentHtml)},on:{\"click\":function($event){$event.preventDefault();return _vm.linkClicked($event)}}}),_vm._v(\" \"),(_vm.showingLongSubject)?_c('a',{staticClass:\"status-unhider\",attrs:{\"href\":\"#\"},on:{\"click\":function($event){$event.preventDefault();_vm.showingLongSubject=false}}},[_vm._v(_vm._s(_vm.$t(\"general.show_less\")))]):_vm._e()]):_c('div',{staticClass:\"status-content-wrapper\",class:{'tall-status': _vm.hideTallStatus}},[(_vm.hideTallStatus)?_c('a',{staticClass:\"tall-status-hider\",class:{ 'tall-status-hider_focused': _vm.focused },attrs:{\"href\":\"#\"},on:{\"click\":function($event){$event.preventDefault();return _vm.toggleShowMore($event)}}},[_vm._v(_vm._s(_vm.$t(\"general.show_more\")))]):_vm._e(),_vm._v(\" \"),(!_vm.hideSubjectStatus)?_c('div',{staticClass:\"status-content media-body\",domProps:{\"innerHTML\":_vm._s(_vm.contentHtml)},on:{\"click\":function($event){$event.preventDefault();return _vm.linkClicked($event)}}}):_c('div',{staticClass:\"status-content media-body\",domProps:{\"innerHTML\":_vm._s(_vm.status.summary_html)},on:{\"click\":function($event){$event.preventDefault();return _vm.linkClicked($event)}}}),_vm._v(\" \"),(_vm.hideSubjectStatus)?_c('a',{staticClass:\"cw-status-hider\",attrs:{\"href\":\"#\"},on:{\"click\":function($event){$event.preventDefault();return _vm.toggleShowMore($event)}}},[_vm._v(_vm._s(_vm.$t(\"general.show_more\")))]):_vm._e(),_vm._v(\" \"),(_vm.showingMore)?_c('a',{staticClass:\"status-unhider\",attrs:{\"href\":\"#\"},on:{\"click\":function($event){$event.preventDefault();return _vm.toggleShowMore($event)}}},[_vm._v(_vm._s(_vm.$t(\"general.show_less\")))]):_vm._e()]),_vm._v(\" \"),(_vm.status.poll && _vm.status.poll.options)?_c('div',[_c('poll',{attrs:{\"base-poll\":_vm.status.poll}})],1):_vm._e(),_vm._v(\" \"),(_vm.status.attachments.length !== 0 && (!_vm.hideSubjectStatus || _vm.showingLongSubject))?_c('div',{staticClass:\"attachments media-body\"},[_vm._l((_vm.nonGalleryAttachments),function(attachment){return _c('attachment',{key:attachment.id,staticClass:\"non-gallery\",attrs:{\"size\":_vm.attachmentSize,\"nsfw\":_vm.nsfwClickthrough,\"attachment\":attachment,\"allow-play\":true,\"set-media\":_vm.setMedia()}})}),_vm._v(\" \"),(_vm.galleryAttachments.length > 0)?_c('gallery',{attrs:{\"nsfw\":_vm.nsfwClickthrough,\"attachments\":_vm.galleryAttachments,\"set-media\":_vm.setMedia()}}):_vm._e()],2):_vm._e(),_vm._v(\" \"),(_vm.status.card && !_vm.hideSubjectStatus && !_vm.noHeading)?_c('div',{staticClass:\"link-preview media-body\"},[_c('link-preview',{attrs:{\"card\":_vm.status.card,\"size\":_vm.attachmentSize,\"nsfw\":_vm.nsfwClickthrough}})],1):_vm._e(),_vm._v(\" \"),_vm._t(\"footer\")],2)}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import { find } from 'lodash'\n\nconst StatusPopover = {\n name: 'StatusPopover',\n props: [\n 'statusId'\n ],\n data () {\n return {\n error: false\n }\n },\n computed: {\n status () {\n return find(this.$store.state.statuses.allStatuses, { id: this.statusId })\n }\n },\n components: {\n Status: () => import('../status/status.vue'),\n Popover: () => import('../popover/popover.vue')\n },\n methods: {\n enter () {\n if (!this.status) {\n this.$store.dispatch('fetchStatus', this.statusId)\n .then(data => (this.error = false))\n .catch(e => (this.error = true))\n }\n }\n }\n}\n\nexport default StatusPopover\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./status_popover.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./status_popover.js\"\nimport __vue_script__ from \"!!babel-loader!./status_popover.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-3b873076\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./status_popover.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('Popover',{attrs:{\"trigger\":\"hover\",\"popover-class\":\"status-popover\",\"bound-to\":{ x: 'container' }},on:{\"show\":_vm.enter}},[_c('template',{slot:\"trigger\"},[_vm._t(\"default\")],2),_vm._v(\" \"),_c('div',{attrs:{\"slot\":\"content\"},slot:\"content\"},[(_vm.status)?_c('Status',{attrs:{\"is-preview\":true,\"statusoid\":_vm.status,\"compact\":true}}):(_vm.error)?_c('div',{staticClass:\"status-preview-no-content faint\"},[_vm._v(\"\\n \"+_vm._s(_vm.$t('status.status_unavailable'))+\"\\n \")]):_c('div',{staticClass:\"status-preview-no-content\"},[_c('i',{staticClass:\"icon-spin4 animate-spin\"})])],1)],2)}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import UserAvatar from '../user_avatar/user_avatar.vue'\nimport Popover from '../popover/popover.vue'\n\nconst EMOJI_REACTION_COUNT_CUTOFF = 12\n\nconst EmojiReactions = {\n name: 'EmojiReactions',\n components: {\n UserAvatar,\n Popover\n },\n props: ['status'],\n data: () => ({\n showAll: false\n }),\n computed: {\n tooManyReactions () {\n return this.status.emoji_reactions.length > EMOJI_REACTION_COUNT_CUTOFF\n },\n emojiReactions () {\n return this.showAll\n ? this.status.emoji_reactions\n : this.status.emoji_reactions.slice(0, EMOJI_REACTION_COUNT_CUTOFF)\n },\n showMoreString () {\n return `+${this.status.emoji_reactions.length - EMOJI_REACTION_COUNT_CUTOFF}`\n },\n accountsForEmoji () {\n return this.status.emoji_reactions.reduce((acc, reaction) => {\n acc[reaction.name] = reaction.accounts || []\n return acc\n }, {})\n },\n loggedIn () {\n return !!this.$store.state.users.currentUser\n }\n },\n methods: {\n toggleShowAll () {\n this.showAll = !this.showAll\n },\n reactedWith (emoji) {\n return this.status.emoji_reactions.find(r => r.name === emoji).me\n },\n fetchEmojiReactionsByIfMissing () {\n const hasNoAccounts = this.status.emoji_reactions.find(r => !r.accounts)\n if (hasNoAccounts) {\n this.$store.dispatch('fetchEmojiReactionsBy', this.status.id)\n }\n },\n reactWith (emoji) {\n this.$store.dispatch('reactWithEmoji', { id: this.status.id, emoji })\n },\n unreact (emoji) {\n this.$store.dispatch('unreactWithEmoji', { id: this.status.id, emoji })\n },\n emojiOnClick (emoji, event) {\n if (!this.loggedIn) return\n\n if (this.reactedWith(emoji)) {\n this.unreact(emoji)\n } else {\n this.reactWith(emoji)\n }\n }\n }\n}\n\nexport default EmojiReactions\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./emoji_reactions.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./emoji_reactions.js\"\nimport __vue_script__ from \"!!babel-loader!./emoji_reactions.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-09ec7fb6\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./emoji_reactions.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"emoji-reactions\"},[_vm._l((_vm.emojiReactions),function(reaction){return _c('Popover',{key:reaction.name,attrs:{\"trigger\":\"hover\",\"placement\":\"top\",\"offset\":{ y: 5 }}},[_c('div',{staticClass:\"reacted-users\",attrs:{\"slot\":\"content\"},slot:\"content\"},[(_vm.accountsForEmoji[reaction.name].length)?_c('div',_vm._l((_vm.accountsForEmoji[reaction.name]),function(account){return _c('div',{key:account.id,staticClass:\"reacted-user\"},[_c('UserAvatar',{staticClass:\"avatar-small\",attrs:{\"user\":account,\"compact\":true}}),_vm._v(\" \"),_c('div',{staticClass:\"reacted-user-names\"},[_c('span',{staticClass:\"reacted-user-name\",domProps:{\"innerHTML\":_vm._s(account.name_html)}}),_vm._v(\" \"),_c('span',{staticClass:\"reacted-user-screen-name\"},[_vm._v(_vm._s(account.screen_name))])])],1)}),0):_c('div',[_c('i',{staticClass:\"icon-spin4 animate-spin\"})])]),_vm._v(\" \"),_c('button',{staticClass:\"emoji-reaction btn btn-default\",class:{ 'picked-reaction': _vm.reactedWith(reaction.name), 'not-clickable': !_vm.loggedIn },attrs:{\"slot\":\"trigger\"},on:{\"click\":function($event){return _vm.emojiOnClick(reaction.name, $event)},\"mouseenter\":function($event){return _vm.fetchEmojiReactionsByIfMissing()}},slot:\"trigger\"},[_c('span',{staticClass:\"reaction-emoji\"},[_vm._v(_vm._s(reaction.name))]),_vm._v(\" \"),_c('span',[_vm._v(_vm._s(reaction.count))])])])}),_vm._v(\" \"),(_vm.tooManyReactions)?_c('a',{staticClass:\"emoji-reaction-expand faint\",attrs:{\"href\":\"javascript:void(0)\"},on:{\"click\":_vm.toggleShowAll}},[_vm._v(\"\\n \"+_vm._s(_vm.showAll ? _vm.$t('general.show_less') : _vm.showMoreString)+\"\\n \")]):_vm._e()],2)}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import FavoriteButton from '../favorite_button/favorite_button.vue'\nimport ReactButton from '../react_button/react_button.vue'\nimport RetweetButton from '../retweet_button/retweet_button.vue'\nimport ExtraButtons from '../extra_buttons/extra_buttons.vue'\nimport PostStatusForm from '../post_status_form/post_status_form.vue'\nimport UserCard from '../user_card/user_card.vue'\nimport UserAvatar from '../user_avatar/user_avatar.vue'\nimport AvatarList from '../avatar_list/avatar_list.vue'\nimport Timeago from '../timeago/timeago.vue'\nimport StatusContent from '../status_content/status_content.vue'\nimport StatusPopover from '../status_popover/status_popover.vue'\nimport EmojiReactions from '../emoji_reactions/emoji_reactions.vue'\nimport generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'\nimport { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'\nimport { filter, unescape, uniqBy } from 'lodash'\nimport { mapGetters, mapState } from 'vuex'\n\nconst Status = {\n name: 'Status',\n props: [\n 'statusoid',\n 'expandable',\n 'inConversation',\n 'focused',\n 'highlight',\n 'compact',\n 'replies',\n 'isPreview',\n 'noHeading',\n 'inlineExpanded',\n 'showPinned',\n 'inProfile',\n 'profileUserId'\n ],\n data () {\n return {\n replying: false,\n unmuted: false,\n userExpanded: false,\n error: null\n }\n },\n computed: {\n muteWords () {\n return this.mergedConfig.muteWords\n },\n repeaterClass () {\n const user = this.statusoid.user\n return highlightClass(user)\n },\n userClass () {\n const user = this.retweet ? (this.statusoid.retweeted_status.user) : this.statusoid.user\n return highlightClass(user)\n },\n deleted () {\n return this.statusoid.deleted\n },\n repeaterStyle () {\n const user = this.statusoid.user\n const highlight = this.mergedConfig.highlight\n return highlightStyle(highlight[user.screen_name])\n },\n userStyle () {\n if (this.noHeading) return\n const user = this.retweet ? (this.statusoid.retweeted_status.user) : this.statusoid.user\n const highlight = this.mergedConfig.highlight\n return highlightStyle(highlight[user.screen_name])\n },\n userProfileLink () {\n return this.generateUserProfileLink(this.status.user.id, this.status.user.screen_name)\n },\n replyProfileLink () {\n if (this.isReply) {\n return this.generateUserProfileLink(this.status.in_reply_to_user_id, this.replyToName)\n }\n },\n retweet () { return !!this.statusoid.retweeted_status },\n retweeter () { return this.statusoid.user.name || this.statusoid.user.screen_name },\n retweeterHtml () { return this.statusoid.user.name_html },\n retweeterProfileLink () { return this.generateUserProfileLink(this.statusoid.user.id, this.statusoid.user.screen_name) },\n status () {\n if (this.retweet) {\n return this.statusoid.retweeted_status\n } else {\n return this.statusoid\n }\n },\n statusFromGlobalRepository () {\n // NOTE: Consider to replace status with statusFromGlobalRepository\n return this.$store.state.statuses.allStatusesObject[this.status.id]\n },\n loggedIn () {\n return !!this.currentUser\n },\n muteWordHits () {\n const statusText = this.status.text.toLowerCase()\n const statusSummary = this.status.summary.toLowerCase()\n const hits = filter(this.muteWords, (muteWord) => {\n return statusText.includes(muteWord.toLowerCase()) || statusSummary.includes(muteWord.toLowerCase())\n })\n\n return hits\n },\n muted () {\n const relationship = this.$store.getters.relationship(this.status.user.id)\n return !this.unmuted && (\n (!(this.inProfile && this.status.user.id === this.profileUserId) && relationship.muting) ||\n (!this.inConversation && this.status.thread_muted) ||\n this.muteWordHits.length > 0)\n },\n hideFilteredStatuses () {\n return this.mergedConfig.hideFilteredStatuses\n },\n hideStatus () {\n return (this.hideReply || this.deleted) || (this.muted && this.hideFilteredStatuses)\n },\n isFocused () {\n // retweet or root of an expanded conversation\n if (this.focused) {\n return true\n } else if (!this.inConversation) {\n return false\n }\n // use conversation highlight only when in conversation\n return this.status.id === this.highlight\n },\n isReply () {\n return !!(this.status.in_reply_to_status_id && this.status.in_reply_to_user_id)\n },\n replyToName () {\n if (this.status.in_reply_to_screen_name) {\n return this.status.in_reply_to_screen_name\n } else {\n const user = this.$store.getters.findUser(this.status.in_reply_to_user_id)\n return user && user.screen_name\n }\n },\n hideReply () {\n if (this.mergedConfig.replyVisibility === 'all') {\n return false\n }\n if (this.inConversation || !this.isReply) {\n return false\n }\n if (this.status.user.id === this.currentUser.id) {\n return false\n }\n if (this.status.type === 'retweet') {\n return false\n }\n const checkFollowing = this.mergedConfig.replyVisibility === 'following'\n for (var i = 0; i < this.status.attentions.length; ++i) {\n if (this.status.user.id === this.status.attentions[i].id) {\n continue\n }\n // There's zero guarantee of this working. If we happen to have that user and their\n // relationship in store then it will work, but there's kinda little chance of having\n // them for people you're not following.\n const relationship = this.$store.state.users.relationships[this.status.attentions[i].id]\n if (checkFollowing && relationship && relationship.following) {\n return false\n }\n if (this.status.attentions[i].id === this.currentUser.id) {\n return false\n }\n }\n return this.status.attentions.length > 0\n },\n replySubject () {\n if (!this.status.summary) return ''\n const decodedSummary = unescape(this.status.summary)\n const behavior = this.mergedConfig.subjectLineBehavior\n const startsWithRe = decodedSummary.match(/^re[: ]/i)\n if ((behavior !== 'noop' && startsWithRe) || behavior === 'masto') {\n return decodedSummary\n } else if (behavior === 'email') {\n return 're: '.concat(decodedSummary)\n } else if (behavior === 'noop') {\n return ''\n }\n },\n combinedFavsAndRepeatsUsers () {\n // Use the status from the global status repository since favs and repeats are saved in it\n const combinedUsers = [].concat(\n this.statusFromGlobalRepository.favoritedBy,\n this.statusFromGlobalRepository.rebloggedBy\n )\n return uniqBy(combinedUsers, 'id')\n },\n tags () {\n return this.status.tags.filter(tagObj => tagObj.hasOwnProperty('name')).map(tagObj => tagObj.name).join(' ')\n },\n hidePostStats () {\n return this.mergedConfig.hidePostStats\n },\n ...mapGetters(['mergedConfig']),\n ...mapState({\n betterShadow: state => state.interface.browserSupport.cssFilter,\n currentUser: state => state.users.currentUser\n })\n },\n components: {\n FavoriteButton,\n ReactButton,\n RetweetButton,\n ExtraButtons,\n PostStatusForm,\n UserCard,\n UserAvatar,\n AvatarList,\n Timeago,\n StatusPopover,\n EmojiReactions,\n StatusContent\n },\n methods: {\n visibilityIcon (visibility) {\n switch (visibility) {\n case 'private':\n return 'icon-lock'\n case 'unlisted':\n return 'icon-lock-open-alt'\n case 'direct':\n return 'icon-mail-alt'\n default:\n return 'icon-globe'\n }\n },\n showError (error) {\n this.error = error\n },\n clearError () {\n this.error = undefined\n },\n toggleReplying () {\n this.replying = !this.replying\n },\n gotoOriginal (id) {\n if (this.inConversation) {\n this.$emit('goto', id)\n }\n },\n toggleExpanded () {\n this.$emit('toggleExpanded')\n },\n toggleMute () {\n this.unmuted = !this.unmuted\n },\n toggleUserExpanded () {\n this.userExpanded = !this.userExpanded\n },\n generateUserProfileLink (id, name) {\n return generateProfileLink(id, name, this.$store.state.instance.restrictedNicknames)\n }\n },\n watch: {\n 'highlight': function (id) {\n if (this.status.id === id) {\n let rect = this.$el.getBoundingClientRect()\n if (rect.top < 100) {\n // Post is above screen, match its top to screen top\n window.scrollBy(0, rect.top - 100)\n } else if (rect.height >= (window.innerHeight - 50)) {\n // Post we want to see is taller than screen so match its top to screen top\n window.scrollBy(0, rect.top - 100)\n } else if (rect.bottom > window.innerHeight - 50) {\n // Post is below screen, match its bottom to screen bottom\n window.scrollBy(0, rect.bottom - window.innerHeight + 50)\n }\n }\n },\n 'status.repeat_num': function (num) {\n // refetch repeats when repeat_num is changed in any way\n if (this.isFocused && this.statusFromGlobalRepository.rebloggedBy && this.statusFromGlobalRepository.rebloggedBy.length !== num) {\n this.$store.dispatch('fetchRepeats', this.status.id)\n }\n },\n 'status.fave_num': function (num) {\n // refetch favs when fave_num is changed in any way\n if (this.isFocused && this.statusFromGlobalRepository.favoritedBy && this.statusFromGlobalRepository.favoritedBy.length !== num) {\n this.$store.dispatch('fetchFavs', this.status.id)\n }\n }\n },\n filters: {\n capitalize: function (str) {\n return str.charAt(0).toUpperCase() + str.slice(1)\n }\n }\n}\n\nexport default Status\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./status.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./status.js\"\nimport __vue_script__ from \"!!babel-loader!./status.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-2d68efa0\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./status.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return (!_vm.hideStatus)?_c('div',{staticClass:\"status-el\",class:[{ 'status-el_focused': _vm.isFocused }, { 'status-conversation': _vm.inlineExpanded }]},[(_vm.error)?_c('div',{staticClass:\"alert error\"},[_vm._v(\"\\n \"+_vm._s(_vm.error)+\"\\n \"),_c('i',{staticClass:\"button-icon icon-cancel\",on:{\"click\":_vm.clearError}})]):_vm._e(),_vm._v(\" \"),(_vm.muted && !_vm.isPreview)?[_c('div',{staticClass:\"media status container muted\"},[_c('small',[_c('router-link',{attrs:{\"to\":_vm.userProfileLink}},[_vm._v(\"\\n \"+_vm._s(_vm.status.user.screen_name)+\"\\n \")])],1),_vm._v(\" \"),_c('small',{staticClass:\"muteWords\"},[_vm._v(_vm._s(_vm.muteWordHits.join(', ')))]),_vm._v(\" \"),_c('a',{staticClass:\"unmute\",attrs:{\"href\":\"#\"},on:{\"click\":function($event){$event.preventDefault();return _vm.toggleMute($event)}}},[_c('i',{staticClass:\"button-icon icon-eye-off\"})])])]:[(_vm.showPinned)?_c('div',{staticClass:\"status-pin\"},[_c('i',{staticClass:\"fa icon-pin faint\"}),_vm._v(\" \"),_c('span',{staticClass:\"faint\"},[_vm._v(_vm._s(_vm.$t('status.pinned')))])]):_vm._e(),_vm._v(\" \"),(_vm.retweet && !_vm.noHeading && !_vm.inConversation)?_c('div',{staticClass:\"media container retweet-info\",class:[_vm.repeaterClass, { highlighted: _vm.repeaterStyle }],style:([_vm.repeaterStyle])},[(_vm.retweet)?_c('UserAvatar',{staticClass:\"media-left\",attrs:{\"better-shadow\":_vm.betterShadow,\"user\":_vm.statusoid.user}}):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"media-body faint\"},[_c('span',{staticClass:\"user-name\"},[(_vm.retweeterHtml)?_c('router-link',{attrs:{\"to\":_vm.retweeterProfileLink},domProps:{\"innerHTML\":_vm._s(_vm.retweeterHtml)}}):_c('router-link',{attrs:{\"to\":_vm.retweeterProfileLink}},[_vm._v(_vm._s(_vm.retweeter))])],1),_vm._v(\" \"),_c('i',{staticClass:\"fa icon-retweet retweeted\",attrs:{\"title\":_vm.$t('tool_tip.repeat')}}),_vm._v(\"\\n \"+_vm._s(_vm.$t('timeline.repeated'))+\"\\n \")])],1):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"media status\",class:[_vm.userClass, { highlighted: _vm.userStyle, 'is-retweet': _vm.retweet && !_vm.inConversation }],style:([ _vm.userStyle ]),attrs:{\"data-tags\":_vm.tags}},[(!_vm.noHeading)?_c('div',{staticClass:\"media-left\"},[_c('router-link',{attrs:{\"to\":_vm.userProfileLink},nativeOn:{\"!click\":function($event){$event.stopPropagation();$event.preventDefault();return _vm.toggleUserExpanded($event)}}},[_c('UserAvatar',{attrs:{\"compact\":_vm.compact,\"better-shadow\":_vm.betterShadow,\"user\":_vm.status.user}})],1)],1):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"status-body\"},[(_vm.userExpanded)?_c('UserCard',{staticClass:\"status-usercard\",attrs:{\"user-id\":_vm.status.user.id,\"rounded\":true,\"bordered\":true}}):_vm._e(),_vm._v(\" \"),(!_vm.noHeading)?_c('div',{staticClass:\"media-heading\"},[_c('div',{staticClass:\"heading-name-row\"},[_c('div',{staticClass:\"name-and-account-name\"},[(_vm.status.user.name_html)?_c('h4',{staticClass:\"user-name\",domProps:{\"innerHTML\":_vm._s(_vm.status.user.name_html)}}):_c('h4',{staticClass:\"user-name\"},[_vm._v(\"\\n \"+_vm._s(_vm.status.user.name)+\"\\n \")]),_vm._v(\" \"),_c('router-link',{staticClass:\"account-name\",attrs:{\"to\":_vm.userProfileLink}},[_vm._v(\"\\n \"+_vm._s(_vm.status.user.screen_name)+\"\\n \")])],1),_vm._v(\" \"),_c('span',{staticClass:\"heading-right\"},[_c('router-link',{staticClass:\"timeago faint-link\",attrs:{\"to\":{ name: 'conversation', params: { id: _vm.status.id } }}},[_c('Timeago',{attrs:{\"time\":_vm.status.created_at,\"auto-update\":60}})],1),_vm._v(\" \"),(_vm.status.visibility)?_c('div',{staticClass:\"button-icon visibility-icon\"},[_c('i',{class:_vm.visibilityIcon(_vm.status.visibility),attrs:{\"title\":_vm._f(\"capitalize\")(_vm.status.visibility)}})]):_vm._e(),_vm._v(\" \"),(!_vm.status.is_local && !_vm.isPreview)?_c('a',{staticClass:\"source_url\",attrs:{\"href\":_vm.status.external_url,\"target\":\"_blank\",\"title\":\"Source\"}},[_c('i',{staticClass:\"button-icon icon-link-ext-alt\"})]):_vm._e(),_vm._v(\" \"),(_vm.expandable && !_vm.isPreview)?[_c('a',{attrs:{\"href\":\"#\",\"title\":\"Expand\"},on:{\"click\":function($event){$event.preventDefault();return _vm.toggleExpanded($event)}}},[_c('i',{staticClass:\"button-icon icon-plus-squared\"})])]:_vm._e(),_vm._v(\" \"),(_vm.unmuted)?_c('a',{attrs:{\"href\":\"#\"},on:{\"click\":function($event){$event.preventDefault();return _vm.toggleMute($event)}}},[_c('i',{staticClass:\"button-icon icon-eye-off\"})]):_vm._e()],2)]),_vm._v(\" \"),_c('div',{staticClass:\"heading-reply-row\"},[(_vm.isReply)?_c('div',{staticClass:\"reply-to-and-accountname\"},[(!_vm.isPreview)?_c('StatusPopover',{staticClass:\"reply-to-popover\",staticStyle:{\"min-width\":\"0\"},attrs:{\"status-id\":_vm.status.in_reply_to_status_id}},[_c('a',{staticClass:\"reply-to\",attrs:{\"href\":\"#\",\"aria-label\":_vm.$t('tool_tip.reply')},on:{\"click\":function($event){$event.preventDefault();return _vm.gotoOriginal(_vm.status.in_reply_to_status_id)}}},[_c('i',{staticClass:\"button-icon icon-reply\"}),_vm._v(\" \"),_c('span',{staticClass:\"faint-link reply-to-text\"},[_vm._v(_vm._s(_vm.$t('status.reply_to')))])])]):_c('span',{staticClass:\"reply-to\"},[_c('span',{staticClass:\"reply-to-text\"},[_vm._v(_vm._s(_vm.$t('status.reply_to')))])]),_vm._v(\" \"),_c('router-link',{attrs:{\"to\":_vm.replyProfileLink}},[_vm._v(\"\\n \"+_vm._s(_vm.replyToName)+\"\\n \")]),_vm._v(\" \"),(_vm.replies && _vm.replies.length)?_c('span',{staticClass:\"faint replies-separator\"},[_vm._v(\"\\n -\\n \")]):_vm._e()],1):_vm._e(),_vm._v(\" \"),(_vm.inConversation && !_vm.isPreview && _vm.replies && _vm.replies.length)?_c('div',{staticClass:\"replies\"},[_c('span',{staticClass:\"faint\"},[_vm._v(_vm._s(_vm.$t('status.replies_list')))]),_vm._v(\" \"),_vm._l((_vm.replies),function(reply){return _c('StatusPopover',{key:reply.id,attrs:{\"status-id\":reply.id}},[_c('a',{staticClass:\"reply-link\",attrs:{\"href\":\"#\"},on:{\"click\":function($event){$event.preventDefault();return _vm.gotoOriginal(reply.id)}}},[_vm._v(_vm._s(reply.name))])])})],2):_vm._e()])]):_vm._e(),_vm._v(\" \"),_c('StatusContent',{attrs:{\"status\":_vm.status,\"no-heading\":_vm.noHeading,\"highlight\":_vm.highlight,\"focused\":_vm.isFocused}}),_vm._v(\" \"),_c('transition',{attrs:{\"name\":\"fade\"}},[(!_vm.hidePostStats && _vm.isFocused && _vm.combinedFavsAndRepeatsUsers.length > 0)?_c('div',{staticClass:\"favs-repeated-users\"},[_c('div',{staticClass:\"stats\"},[(_vm.statusFromGlobalRepository.rebloggedBy && _vm.statusFromGlobalRepository.rebloggedBy.length > 0)?_c('div',{staticClass:\"stat-count\"},[_c('a',{staticClass:\"stat-title\"},[_vm._v(_vm._s(_vm.$t('status.repeats')))]),_vm._v(\" \"),_c('div',{staticClass:\"stat-number\"},[_vm._v(\"\\n \"+_vm._s(_vm.statusFromGlobalRepository.rebloggedBy.length)+\"\\n \")])]):_vm._e(),_vm._v(\" \"),(_vm.statusFromGlobalRepository.favoritedBy && _vm.statusFromGlobalRepository.favoritedBy.length > 0)?_c('div',{staticClass:\"stat-count\"},[_c('a',{staticClass:\"stat-title\"},[_vm._v(_vm._s(_vm.$t('status.favorites')))]),_vm._v(\" \"),_c('div',{staticClass:\"stat-number\"},[_vm._v(\"\\n \"+_vm._s(_vm.statusFromGlobalRepository.favoritedBy.length)+\"\\n \")])]):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"avatar-row\"},[_c('AvatarList',{attrs:{\"users\":_vm.combinedFavsAndRepeatsUsers}})],1)])]):_vm._e()]),_vm._v(\" \"),((_vm.mergedConfig.emojiReactionsOnTimeline || _vm.isFocused) && (!_vm.noHeading && !_vm.isPreview))?_c('EmojiReactions',{attrs:{\"status\":_vm.status}}):_vm._e(),_vm._v(\" \"),(!_vm.noHeading && !_vm.isPreview)?_c('div',{staticClass:\"status-actions media-body\"},[_c('div',[(_vm.loggedIn)?_c('i',{staticClass:\"button-icon icon-reply\",class:{'button-icon-active': _vm.replying},attrs:{\"title\":_vm.$t('tool_tip.reply')},on:{\"click\":function($event){$event.preventDefault();return _vm.toggleReplying($event)}}}):_c('i',{staticClass:\"button-icon button-icon-disabled icon-reply\",attrs:{\"title\":_vm.$t('tool_tip.reply')}}),_vm._v(\" \"),(_vm.status.replies_count > 0)?_c('span',[_vm._v(_vm._s(_vm.status.replies_count))]):_vm._e()]),_vm._v(\" \"),_c('retweet-button',{attrs:{\"visibility\":_vm.status.visibility,\"logged-in\":_vm.loggedIn,\"status\":_vm.status}}),_vm._v(\" \"),_c('favorite-button',{attrs:{\"logged-in\":_vm.loggedIn,\"status\":_vm.status}}),_vm._v(\" \"),(_vm.loggedIn)?_c('ReactButton',{attrs:{\"status\":_vm.status}}):_vm._e(),_vm._v(\" \"),_c('extra-buttons',{attrs:{\"status\":_vm.status},on:{\"onError\":_vm.showError,\"onSuccess\":_vm.clearError}})],1):_vm._e()],1)]),_vm._v(\" \"),(_vm.replying)?_c('div',{staticClass:\"container\"},[_c('PostStatusForm',{staticClass:\"reply-body\",attrs:{\"reply-to\":_vm.status.id,\"attentions\":_vm.status.attentions,\"replied-user\":_vm.status.user,\"copy-message-scope\":_vm.status.visibility,\"subject\":_vm.replySubject},on:{\"posted\":_vm.toggleReplying}})],1):_vm._e()]],2):_vm._e()}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","\nconst Popover = {\n name: 'Popover',\n props: {\n // Action to trigger popover: either 'hover' or 'click'\n trigger: String,\n // Either 'top' or 'bottom'\n placement: String,\n // Takes object with properties 'x' and 'y', values of these can be\n // 'container' for using offsetParent as boundaries for either axis\n // or 'viewport'\n boundTo: Object,\n // Takes a top/bottom/left/right object, how much space to leave\n // between boundary and popover element\n margin: Object,\n // Takes a x/y object and tells how many pixels to offset from\n // anchor point on either axis\n offset: Object,\n // Additional styles you may want for the popover container\n popoverClass: String\n },\n data () {\n return {\n hidden: true,\n styles: { opacity: 0 },\n oldSize: { width: 0, height: 0 }\n }\n },\n methods: {\n updateStyles () {\n if (this.hidden) {\n this.styles = {\n opacity: 0\n }\n return\n }\n\n // Popover will be anchored around this element, trigger ref is the container, so\n // its children are what are inside the slot. Expect only one slot=\"trigger\".\n const anchorEl = (this.$refs.trigger && this.$refs.trigger.children[0]) || this.$el\n const screenBox = anchorEl.getBoundingClientRect()\n // Screen position of the origin point for popover\n const origin = { x: screenBox.left + screenBox.width * 0.5, y: screenBox.top }\n const content = this.$refs.content\n // Minor optimization, don't call a slow reflow call if we don't have to\n const parentBounds = this.boundTo &&\n (this.boundTo.x === 'container' || this.boundTo.y === 'container') &&\n this.$el.offsetParent.getBoundingClientRect()\n const margin = this.margin || {}\n\n // What are the screen bounds for the popover? Viewport vs container\n // when using viewport, using default margin values to dodge the navbar\n const xBounds = this.boundTo && this.boundTo.x === 'container' ? {\n min: parentBounds.left + (margin.left || 0),\n max: parentBounds.right - (margin.right || 0)\n } : {\n min: 0 + (margin.left || 10),\n max: window.innerWidth - (margin.right || 10)\n }\n\n const yBounds = this.boundTo && this.boundTo.y === 'container' ? {\n min: parentBounds.top + (margin.top || 0),\n max: parentBounds.bottom - (margin.bottom || 0)\n } : {\n min: 0 + (margin.top || 50),\n max: window.innerHeight - (margin.bottom || 5)\n }\n\n let horizOffset = 0\n\n // If overflowing from left, move it so that it doesn't\n if ((origin.x - content.offsetWidth * 0.5) < xBounds.min) {\n horizOffset += -(origin.x - content.offsetWidth * 0.5) + xBounds.min\n }\n\n // If overflowing from right, move it so that it doesn't\n if ((origin.x + horizOffset + content.offsetWidth * 0.5) > xBounds.max) {\n horizOffset -= (origin.x + horizOffset + content.offsetWidth * 0.5) - xBounds.max\n }\n\n // Default to whatever user wished with placement prop\n let usingTop = this.placement !== 'bottom'\n\n // Handle special cases, first force to displaying on top if there's not space on bottom,\n // regardless of what placement value was. Then check if there's not space on top, and\n // force to bottom, again regardless of what placement value was.\n if (origin.y + content.offsetHeight > yBounds.max) usingTop = true\n if (origin.y - content.offsetHeight < yBounds.min) usingTop = false\n\n const yOffset = (this.offset && this.offset.y) || 0\n const translateY = usingTop\n ? -anchorEl.offsetHeight - yOffset - content.offsetHeight\n : yOffset\n\n const xOffset = (this.offset && this.offset.x) || 0\n const translateX = (anchorEl.offsetWidth * 0.5) - content.offsetWidth * 0.5 + horizOffset + xOffset\n\n // Note, separate translateX and translateY avoids blurry text on chromium,\n // single translate or translate3d resulted in blurry text.\n this.styles = {\n opacity: 1,\n transform: `translateX(${Math.floor(translateX)}px) translateY(${Math.floor(translateY)}px)`\n }\n },\n showPopover () {\n if (this.hidden) this.$emit('show')\n this.hidden = false\n this.$nextTick(this.updateStyles)\n },\n hidePopover () {\n if (!this.hidden) this.$emit('close')\n this.hidden = true\n this.styles = { opacity: 0 }\n },\n onMouseenter (e) {\n if (this.trigger === 'hover') this.showPopover()\n },\n onMouseleave (e) {\n if (this.trigger === 'hover') this.hidePopover()\n },\n onClick (e) {\n if (this.trigger === 'click') {\n if (this.hidden) {\n this.showPopover()\n } else {\n this.hidePopover()\n }\n }\n },\n onClickOutside (e) {\n if (this.hidden) return\n if (this.$el.contains(e.target)) return\n this.hidePopover()\n }\n },\n updated () {\n // Monitor changes to content size, update styles only when content sizes have changed,\n // that should be the only time we need to move the popover box if we don't care about scroll\n // or resize\n const content = this.$refs.content\n if (!content) return\n if (this.oldSize.width !== content.offsetWidth || this.oldSize.height !== content.offsetHeight) {\n this.updateStyles()\n this.oldSize = { width: content.offsetWidth, height: content.offsetHeight }\n }\n },\n created () {\n document.addEventListener('click', this.onClickOutside)\n },\n destroyed () {\n document.removeEventListener('click', this.onClickOutside)\n this.hidePopover()\n }\n}\n\nexport default Popover\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./popover.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./popover.js\"\nimport __vue_script__ from \"!!babel-loader!./popover.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-10f1984d\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./popover.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{on:{\"mouseenter\":_vm.onMouseenter,\"mouseleave\":_vm.onMouseleave}},[_c('div',{ref:\"trigger\",on:{\"click\":_vm.onClick}},[_vm._t(\"trigger\")],2),_vm._v(\" \"),(!_vm.hidden)?_c('div',{ref:\"content\",staticClass:\"popover\",class:_vm.popoverClass,style:(_vm.styles)},[_vm._t(\"content\",null,{\"close\":_vm.hidePopover})],2):_vm._e()])}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","export const SECOND = 1000\nexport const MINUTE = 60 * SECOND\nexport const HOUR = 60 * MINUTE\nexport const DAY = 24 * HOUR\nexport const WEEK = 7 * DAY\nexport const MONTH = 30 * DAY\nexport const YEAR = 365.25 * DAY\n\nexport const relativeTime = (date, nowThreshold = 1) => {\n if (typeof date === 'string') date = Date.parse(date)\n const round = Date.now() > date ? Math.floor : Math.ceil\n const d = Math.abs(Date.now() - date)\n let r = { num: round(d / YEAR), key: 'time.years' }\n if (d < nowThreshold * SECOND) {\n r.num = 0\n r.key = 'time.now'\n } else if (d < MINUTE) {\n r.num = round(d / SECOND)\n r.key = 'time.seconds'\n } else if (d < HOUR) {\n r.num = round(d / MINUTE)\n r.key = 'time.minutes'\n } else if (d < DAY) {\n r.num = round(d / HOUR)\n r.key = 'time.hours'\n } else if (d < WEEK) {\n r.num = round(d / DAY)\n r.key = 'time.days'\n } else if (d < MONTH) {\n r.num = round(d / WEEK)\n r.key = 'time.weeks'\n } else if (d < YEAR) {\n r.num = round(d / MONTH)\n r.key = 'time.months'\n }\n // Remove plural form when singular\n if (r.num === 1) r.key = r.key.slice(0, -1)\n return r\n}\n\nexport const relativeTimeShort = (date, nowThreshold = 1) => {\n const r = relativeTime(date, nowThreshold)\n r.key += '_short'\n return r\n}\n","\n\n\n","/* script */\nexport * from \"!!babel-loader!../../../node_modules/vue-loader/lib/selector?type=script&index=0!./progress_button.vue\"\nimport __vue_script__ from \"!!babel-loader!../../../node_modules/vue-loader/lib/selector?type=script&index=0!./progress_button.vue\"\n/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-9f751ae6\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./progress_button.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = null\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('button',{attrs:{\"disabled\":_vm.progress || _vm.disabled},on:{\"click\":_vm.onClick}},[(_vm.progress && _vm.$slots.progress)?[_vm._t(\"progress\")]:[_vm._t(\"default\")]],2)}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import { hex2rgb } from '../color_convert/color_convert.js'\nconst highlightStyle = (prefs) => {\n if (prefs === undefined) return\n const { color, type } = prefs\n if (typeof color !== 'string') return\n const rgb = hex2rgb(color)\n if (rgb == null) return\n const solidColor = `rgb(${Math.floor(rgb.r)}, ${Math.floor(rgb.g)}, ${Math.floor(rgb.b)})`\n const tintColor = `rgba(${Math.floor(rgb.r)}, ${Math.floor(rgb.g)}, ${Math.floor(rgb.b)}, .1)`\n const tintColor2 = `rgba(${Math.floor(rgb.r)}, ${Math.floor(rgb.g)}, ${Math.floor(rgb.b)}, .2)`\n if (type === 'striped') {\n return {\n backgroundImage: [\n 'repeating-linear-gradient(135deg,',\n `${tintColor} ,`,\n `${tintColor} 20px,`,\n `${tintColor2} 20px,`,\n `${tintColor2} 40px`\n ].join(' '),\n backgroundPosition: '0 0'\n }\n } else if (type === 'solid') {\n return {\n backgroundColor: tintColor2\n }\n } else if (type === 'side') {\n return {\n backgroundImage: [\n 'linear-gradient(to right,',\n `${solidColor} ,`,\n `${solidColor} 2px,`,\n `transparent 6px`\n ].join(' '),\n backgroundPosition: '0 0'\n }\n }\n}\n\nconst highlightClass = (user) => {\n return 'USER____' + user.screen_name\n .replace(/\\./g, '_')\n .replace(/@/g, '_AT_')\n}\n\nexport {\n highlightClass,\n highlightStyle\n}\n","import Vue from 'vue'\n\nimport './tab_switcher.scss'\n\nexport default Vue.component('tab-switcher', {\n name: 'TabSwitcher',\n props: {\n renderOnlyFocused: {\n required: false,\n type: Boolean,\n default: false\n },\n onSwitch: {\n required: false,\n type: Function,\n default: undefined\n },\n activeTab: {\n required: false,\n type: String,\n default: undefined\n },\n scrollableTabs: {\n required: false,\n type: Boolean,\n default: false\n }\n },\n data () {\n return {\n active: this.$slots.default.findIndex(_ => _.tag)\n }\n },\n computed: {\n activeIndex () {\n // In case of controlled component\n if (this.activeTab) {\n return this.$slots.default.findIndex(slot => this.activeTab === slot.key)\n } else {\n return this.active\n }\n }\n },\n beforeUpdate () {\n const currentSlot = this.$slots.default[this.active]\n if (!currentSlot.tag) {\n this.active = this.$slots.default.findIndex(_ => _.tag)\n }\n },\n methods: {\n activateTab (index) {\n return (e) => {\n e.preventDefault()\n if (typeof this.onSwitch === 'function') {\n this.onSwitch.call(null, this.$slots.default[index].key)\n }\n this.active = index\n }\n }\n },\n render (h) {\n const tabs = this.$slots.default\n .map((slot, index) => {\n if (!slot.tag) return\n const classesTab = ['tab']\n const classesWrapper = ['tab-wrapper']\n\n if (this.activeIndex === index) {\n classesTab.push('active')\n classesWrapper.push('active')\n }\n if (slot.data.attrs.image) {\n return (\n

\n \n \n {slot.data.attrs.label ? '' : slot.data.attrs.label}\n \n
\n )\n }\n return (\n
\n \n {slot.data.attrs.label}\n
\n )\n })\n\n const contents = this.$slots.default.map((slot, index) => {\n if (!slot.tag) return\n const active = this.activeIndex === index\n if (this.renderOnlyFocused) {\n return active\n ?
{slot}
\n :
\n }\n return
{slot}
\n })\n\n return (\n
\n
\n {tabs}\n
\n
\n {contents}\n
\n
\n )\n }\n})\n","/* eslint-env browser */\nimport statusPosterService from '../../services/status_poster/status_poster.service.js'\nimport fileSizeFormatService from '../../services/file_size_format/file_size_format.js'\n\nconst mediaUpload = {\n data () {\n return {\n uploading: false,\n uploadReady: true\n }\n },\n methods: {\n uploadFile (file) {\n const self = this\n const store = this.$store\n if (file.size > store.state.instance.uploadlimit) {\n const filesize = fileSizeFormatService.fileSizeFormat(file.size)\n const allowedsize = fileSizeFormatService.fileSizeFormat(store.state.instance.uploadlimit)\n self.$emit('upload-failed', 'file_too_big', { filesize: filesize.num, filesizeunit: filesize.unit, allowedsize: allowedsize.num, allowedsizeunit: allowedsize.unit })\n return\n }\n const formData = new FormData()\n formData.append('file', file)\n\n self.$emit('uploading')\n self.uploading = true\n\n statusPosterService.uploadMedia({ store, formData })\n .then((fileData) => {\n self.$emit('uploaded', fileData)\n self.uploading = false\n }, (error) => { // eslint-disable-line handle-callback-err\n self.$emit('upload-failed', 'default')\n self.uploading = false\n })\n },\n fileDrop (e) {\n if (e.dataTransfer.files.length > 0) {\n e.preventDefault() // allow dropping text like before\n this.uploadFile(e.dataTransfer.files[0])\n }\n },\n fileDrag (e) {\n let types = e.dataTransfer.types\n if (types.contains('Files')) {\n e.dataTransfer.dropEffect = 'copy'\n } else {\n e.dataTransfer.dropEffect = 'none'\n }\n },\n clearFile () {\n this.uploadReady = false\n this.$nextTick(() => {\n this.uploadReady = true\n })\n },\n change ({ target }) {\n for (var i = 0; i < target.files.length; i++) {\n let file = target.files[i]\n this.uploadFile(file)\n }\n }\n },\n props: [\n 'dropFiles'\n ],\n watch: {\n 'dropFiles': function (fileInfos) {\n if (!this.uploading) {\n this.uploadFile(fileInfos[0])\n }\n }\n }\n}\n\nexport default mediaUpload\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./media_upload.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./media_upload.js\"\nimport __vue_script__ from \"!!babel-loader!./media_upload.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-74382032\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./media_upload.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"media-upload\",on:{\"drop\":[function($event){$event.preventDefault();},_vm.fileDrop],\"dragover\":function($event){$event.preventDefault();return _vm.fileDrag($event)}}},[_c('label',{staticClass:\"label\",attrs:{\"title\":_vm.$t('tool_tip.media_upload')}},[(_vm.uploading)?_c('i',{staticClass:\"progress-icon icon-spin4 animate-spin\"}):_vm._e(),_vm._v(\" \"),(!_vm.uploading)?_c('i',{staticClass:\"new-icon icon-upload\"}):_vm._e(),_vm._v(\" \"),(_vm.uploadReady)?_c('input',{staticStyle:{\"position\":\"fixed\",\"top\":\"-100em\"},attrs:{\"type\":\"file\",\"multiple\":\"true\"},on:{\"change\":_vm.change}}):_vm._e()])])}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import * as DateUtils from 'src/services/date_utils/date_utils.js'\nimport { uniq } from 'lodash'\n\nexport default {\n name: 'PollForm',\n props: ['visible'],\n data: () => ({\n pollType: 'single',\n options: ['', ''],\n expiryAmount: 10,\n expiryUnit: 'minutes'\n }),\n computed: {\n pollLimits () {\n return this.$store.state.instance.pollLimits\n },\n maxOptions () {\n return this.pollLimits.max_options\n },\n maxLength () {\n return this.pollLimits.max_option_chars\n },\n expiryUnits () {\n const allUnits = ['minutes', 'hours', 'days']\n const expiry = this.convertExpiryFromUnit\n return allUnits.filter(\n unit => this.pollLimits.max_expiration >= expiry(unit, 1)\n )\n },\n minExpirationInCurrentUnit () {\n return Math.ceil(\n this.convertExpiryToUnit(\n this.expiryUnit,\n this.pollLimits.min_expiration\n )\n )\n },\n maxExpirationInCurrentUnit () {\n return Math.floor(\n this.convertExpiryToUnit(\n this.expiryUnit,\n this.pollLimits.max_expiration\n )\n )\n }\n },\n methods: {\n clear () {\n this.pollType = 'single'\n this.options = ['', '']\n this.expiryAmount = 10\n this.expiryUnit = 'minutes'\n },\n nextOption (index) {\n const element = this.$el.querySelector(`#poll-${index + 1}`)\n if (element) {\n element.focus()\n } else {\n // Try adding an option and try focusing on it\n const addedOption = this.addOption()\n if (addedOption) {\n this.$nextTick(function () {\n this.nextOption(index)\n })\n }\n }\n },\n addOption () {\n if (this.options.length < this.maxOptions) {\n this.options.push('')\n return true\n }\n return false\n },\n deleteOption (index, event) {\n if (this.options.length > 2) {\n this.options.splice(index, 1)\n }\n },\n convertExpiryToUnit (unit, amount) {\n // Note: we want seconds and not milliseconds\n switch (unit) {\n case 'minutes': return (1000 * amount) / DateUtils.MINUTE\n case 'hours': return (1000 * amount) / DateUtils.HOUR\n case 'days': return (1000 * amount) / DateUtils.DAY\n }\n },\n convertExpiryFromUnit (unit, amount) {\n // Note: we want seconds and not milliseconds\n switch (unit) {\n case 'minutes': return 0.001 * amount * DateUtils.MINUTE\n case 'hours': return 0.001 * amount * DateUtils.HOUR\n case 'days': return 0.001 * amount * DateUtils.DAY\n }\n },\n expiryAmountChange () {\n this.expiryAmount =\n Math.max(this.minExpirationInCurrentUnit, this.expiryAmount)\n this.expiryAmount =\n Math.min(this.maxExpirationInCurrentUnit, this.expiryAmount)\n this.updatePollToParent()\n },\n updatePollToParent () {\n const expiresIn = this.convertExpiryFromUnit(\n this.expiryUnit,\n this.expiryAmount\n )\n\n const options = uniq(this.options.filter(option => option !== ''))\n if (options.length < 2) {\n this.$emit('update-poll', { error: this.$t('polls.not_enough_options') })\n return\n }\n this.$emit('update-poll', {\n options,\n multiple: this.pollType === 'multiple',\n expiresIn\n })\n }\n }\n}\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./poll_form.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./poll_form.js\"\nimport __vue_script__ from \"!!babel-loader!./poll_form.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-1f896331\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./poll_form.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return (_vm.visible)?_c('div',{staticClass:\"poll-form\"},[_vm._l((_vm.options),function(option,index){return _c('div',{key:index,staticClass:\"poll-option\"},[_c('div',{staticClass:\"input-container\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.options[index]),expression:\"options[index]\"}],staticClass:\"poll-option-input\",attrs:{\"id\":(\"poll-\" + index),\"type\":\"text\",\"placeholder\":_vm.$t('polls.option'),\"maxlength\":_vm.maxLength},domProps:{\"value\":(_vm.options[index])},on:{\"change\":_vm.updatePollToParent,\"keydown\":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,\"enter\",13,$event.key,\"Enter\")){ return null; }$event.stopPropagation();$event.preventDefault();return _vm.nextOption(index)},\"input\":function($event){if($event.target.composing){ return; }_vm.$set(_vm.options, index, $event.target.value)}}})]),_vm._v(\" \"),(_vm.options.length > 2)?_c('div',{staticClass:\"icon-container\"},[_c('i',{staticClass:\"icon-cancel\",on:{\"click\":function($event){return _vm.deleteOption(index)}}})]):_vm._e()])}),_vm._v(\" \"),(_vm.options.length < _vm.maxOptions)?_c('a',{staticClass:\"add-option faint\",on:{\"click\":_vm.addOption}},[_c('i',{staticClass:\"icon-plus\"}),_vm._v(\"\\n \"+_vm._s(_vm.$t(\"polls.add_option\"))+\"\\n \")]):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"poll-type-expiry\"},[_c('div',{staticClass:\"poll-type\",attrs:{\"title\":_vm.$t('polls.type')}},[_c('label',{staticClass:\"select\",attrs:{\"for\":\"poll-type-selector\"}},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.pollType),expression:\"pollType\"}],staticClass:\"select\",on:{\"change\":[function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.pollType=$event.target.multiple ? $$selectedVal : $$selectedVal[0]},_vm.updatePollToParent]}},[_c('option',{attrs:{\"value\":\"single\"}},[_vm._v(_vm._s(_vm.$t('polls.single_choice')))]),_vm._v(\" \"),_c('option',{attrs:{\"value\":\"multiple\"}},[_vm._v(_vm._s(_vm.$t('polls.multiple_choices')))])]),_vm._v(\" \"),_c('i',{staticClass:\"icon-down-open\"})])]),_vm._v(\" \"),_c('div',{staticClass:\"poll-expiry\",attrs:{\"title\":_vm.$t('polls.expiry')}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.expiryAmount),expression:\"expiryAmount\"}],staticClass:\"expiry-amount hide-number-spinner\",attrs:{\"type\":\"number\",\"min\":_vm.minExpirationInCurrentUnit,\"max\":_vm.maxExpirationInCurrentUnit},domProps:{\"value\":(_vm.expiryAmount)},on:{\"change\":_vm.expiryAmountChange,\"input\":function($event){if($event.target.composing){ return; }_vm.expiryAmount=$event.target.value}}}),_vm._v(\" \"),_c('label',{staticClass:\"expiry-unit select\"},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.expiryUnit),expression:\"expiryUnit\"}],on:{\"change\":[function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.expiryUnit=$event.target.multiple ? $$selectedVal : $$selectedVal[0]},_vm.expiryAmountChange]}},_vm._l((_vm.expiryUnits),function(unit){return _c('option',{key:unit,domProps:{\"value\":unit}},[_vm._v(\"\\n \"+_vm._s(_vm.$t((\"time.\" + unit + \"_short\"), ['']))+\"\\n \")])}),0),_vm._v(\" \"),_c('i',{staticClass:\"icon-down-open\"})])])])],2):_vm._e()}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import statusPoster from '../../services/status_poster/status_poster.service.js'\nimport MediaUpload from '../media_upload/media_upload.vue'\nimport ScopeSelector from '../scope_selector/scope_selector.vue'\nimport EmojiInput from '../emoji_input/emoji_input.vue'\nimport PollForm from '../poll/poll_form.vue'\nimport fileTypeService from '../../services/file_type/file_type.service.js'\nimport { findOffset } from '../../services/offset_finder/offset_finder.service.js'\nimport { reject, map, uniqBy } from 'lodash'\nimport suggestor from '../emoji_input/suggestor.js'\nimport { mapGetters } from 'vuex'\nimport Checkbox from '../checkbox/checkbox.vue'\n\nconst buildMentionsString = ({ user, attentions = [] }, currentUser) => {\n let allAttentions = [...attentions]\n\n allAttentions.unshift(user)\n\n allAttentions = uniqBy(allAttentions, 'id')\n allAttentions = reject(allAttentions, { id: currentUser.id })\n\n let mentions = map(allAttentions, (attention) => {\n return `@${attention.screen_name}`\n })\n\n return mentions.length > 0 ? mentions.join(' ') + ' ' : ''\n}\n\nconst PostStatusForm = {\n props: [\n 'replyTo',\n 'repliedUser',\n 'attentions',\n 'copyMessageScope',\n 'subject'\n ],\n components: {\n MediaUpload,\n EmojiInput,\n PollForm,\n ScopeSelector,\n Checkbox\n },\n mounted () {\n this.resize(this.$refs.textarea)\n const textLength = this.$refs.textarea.value.length\n this.$refs.textarea.setSelectionRange(textLength, textLength)\n\n if (this.replyTo) {\n this.$refs.textarea.focus()\n }\n },\n data () {\n const preset = this.$route.query.message\n let statusText = preset || ''\n\n const { scopeCopy } = this.$store.getters.mergedConfig\n\n if (this.replyTo) {\n const currentUser = this.$store.state.users.currentUser\n statusText = buildMentionsString({ user: this.repliedUser, attentions: this.attentions }, currentUser)\n }\n\n const scope = ((this.copyMessageScope && scopeCopy) || this.copyMessageScope === 'direct')\n ? this.copyMessageScope\n : this.$store.state.users.currentUser.default_scope\n\n const { postContentType: contentType } = this.$store.getters.mergedConfig\n\n return {\n dropFiles: [],\n submitDisabled: false,\n error: null,\n posting: false,\n highlighted: 0,\n newStatus: {\n spoilerText: this.subject || '',\n status: statusText,\n nsfw: false,\n files: [],\n poll: {},\n visibility: scope,\n contentType\n },\n caret: 0,\n pollFormVisible: false\n }\n },\n computed: {\n users () {\n return this.$store.state.users.users\n },\n userDefaultScope () {\n return this.$store.state.users.currentUser.default_scope\n },\n showAllScopes () {\n return !this.mergedConfig.minimalScopesMode\n },\n emojiUserSuggestor () {\n return suggestor({\n emoji: [\n ...this.$store.state.instance.emoji,\n ...this.$store.state.instance.customEmoji\n ],\n users: this.$store.state.users.users,\n updateUsersList: (input) => this.$store.dispatch('searchUsers', input)\n })\n },\n emojiSuggestor () {\n return suggestor({\n emoji: [\n ...this.$store.state.instance.emoji,\n ...this.$store.state.instance.customEmoji\n ]\n })\n },\n emoji () {\n return this.$store.state.instance.emoji || []\n },\n customEmoji () {\n return this.$store.state.instance.customEmoji || []\n },\n statusLength () {\n return this.newStatus.status.length\n },\n spoilerTextLength () {\n return this.newStatus.spoilerText.length\n },\n statusLengthLimit () {\n return this.$store.state.instance.textlimit\n },\n hasStatusLengthLimit () {\n return this.statusLengthLimit > 0\n },\n charactersLeft () {\n return this.statusLengthLimit - (this.statusLength + this.spoilerTextLength)\n },\n isOverLengthLimit () {\n return this.hasStatusLengthLimit && (this.charactersLeft < 0)\n },\n minimalScopesMode () {\n return this.$store.state.instance.minimalScopesMode\n },\n alwaysShowSubject () {\n return this.mergedConfig.alwaysShowSubjectInput\n },\n postFormats () {\n return this.$store.state.instance.postFormats || []\n },\n safeDMEnabled () {\n return this.$store.state.instance.safeDM\n },\n pollsAvailable () {\n return this.$store.state.instance.pollsAvailable &&\n this.$store.state.instance.pollLimits.max_options >= 2\n },\n hideScopeNotice () {\n return this.$store.getters.mergedConfig.hideScopeNotice\n },\n pollContentError () {\n return this.pollFormVisible &&\n this.newStatus.poll &&\n this.newStatus.poll.error\n },\n ...mapGetters(['mergedConfig'])\n },\n methods: {\n postStatus (newStatus) {\n if (this.posting) { return }\n if (this.submitDisabled) { return }\n\n if (this.newStatus.status === '') {\n if (this.newStatus.files.length === 0) {\n this.error = 'Cannot post an empty status with no files'\n return\n }\n }\n\n const poll = this.pollFormVisible ? this.newStatus.poll : {}\n if (this.pollContentError) {\n this.error = this.pollContentError\n return\n }\n\n this.posting = true\n statusPoster.postStatus({\n status: newStatus.status,\n spoilerText: newStatus.spoilerText || null,\n visibility: newStatus.visibility,\n sensitive: newStatus.nsfw,\n media: newStatus.files,\n store: this.$store,\n inReplyToStatusId: this.replyTo,\n contentType: newStatus.contentType,\n poll\n }).then((data) => {\n if (!data.error) {\n this.newStatus = {\n status: '',\n spoilerText: '',\n files: [],\n visibility: newStatus.visibility,\n contentType: newStatus.contentType,\n poll: {}\n }\n this.pollFormVisible = false\n this.$refs.mediaUpload.clearFile()\n this.clearPollForm()\n this.$emit('posted')\n let el = this.$el.querySelector('textarea')\n el.style.height = 'auto'\n el.style.height = undefined\n this.error = null\n } else {\n this.error = data.error\n }\n this.posting = false\n })\n },\n addMediaFile (fileInfo) {\n this.newStatus.files.push(fileInfo)\n this.enableSubmit()\n },\n removeMediaFile (fileInfo) {\n let index = this.newStatus.files.indexOf(fileInfo)\n this.newStatus.files.splice(index, 1)\n },\n uploadFailed (errString, templateArgs) {\n templateArgs = templateArgs || {}\n this.error = this.$t('upload.error.base') + ' ' + this.$t('upload.error.' + errString, templateArgs)\n this.enableSubmit()\n },\n disableSubmit () {\n this.submitDisabled = true\n },\n enableSubmit () {\n this.submitDisabled = false\n },\n type (fileInfo) {\n return fileTypeService.fileType(fileInfo.mimetype)\n },\n paste (e) {\n this.resize(e)\n if (e.clipboardData.files.length > 0) {\n // prevent pasting of file as text\n e.preventDefault()\n // Strangely, files property gets emptied after event propagation\n // Trying to wrap it in array doesn't work. Plus I doubt it's possible\n // to hold more than one file in clipboard.\n this.dropFiles = [e.clipboardData.files[0]]\n }\n },\n fileDrop (e) {\n if (e.dataTransfer.files.length > 0) {\n e.preventDefault() // allow dropping text like before\n this.dropFiles = e.dataTransfer.files\n }\n },\n fileDrag (e) {\n e.dataTransfer.dropEffect = 'copy'\n },\n onEmojiInputInput (e) {\n this.$nextTick(() => {\n this.resize(this.$refs['textarea'])\n })\n },\n resize (e) {\n const target = e.target || e\n if (!(target instanceof window.Element)) { return }\n\n // Reset to default height for empty form, nothing else to do here.\n if (target.value === '') {\n target.style.height = null\n this.$refs['emoji-input'].resize()\n return\n }\n\n const formRef = this.$refs['form']\n const bottomRef = this.$refs['bottom']\n /* Scroller is either `window` (replies in TL), sidebar (main post form,\n * replies in notifs) or mobile post form. Note that getting and setting\n * scroll is different for `Window` and `Element`s\n */\n const bottomBottomPaddingStr = window.getComputedStyle(bottomRef)['padding-bottom']\n const bottomBottomPadding = Number(bottomBottomPaddingStr.substring(0, bottomBottomPaddingStr.length - 2))\n\n const scrollerRef = this.$el.closest('.sidebar-scroller') ||\n this.$el.closest('.post-form-modal-view') ||\n window\n\n // Getting info about padding we have to account for, removing 'px' part\n const topPaddingStr = window.getComputedStyle(target)['padding-top']\n const bottomPaddingStr = window.getComputedStyle(target)['padding-bottom']\n const topPadding = Number(topPaddingStr.substring(0, topPaddingStr.length - 2))\n const bottomPadding = Number(bottomPaddingStr.substring(0, bottomPaddingStr.length - 2))\n const vertPadding = topPadding + bottomPadding\n\n /* Explanation:\n *\n * https://developer.mozilla.org/en-US/docs/Web/API/Element/scrollHeight\n * scrollHeight returns element's scrollable content height, i.e. visible\n * element + overscrolled parts of it. We use it to determine when text\n * inside the textarea exceeded its height, so we can set height to prevent\n * overscroll, i.e. make textarea grow with the text. HOWEVER, since we\n * explicitly set new height, scrollHeight won't go below that, so we can't\n * SHRINK the textarea when there's extra space. To workaround that we set\n * height to 'auto' which makes textarea tiny again, so that scrollHeight\n * will match text height again. HOWEVER, shrinking textarea can screw with\n * the scroll since there might be not enough padding around form-bottom to even\n * warrant a scroll, so it will jump to 0 and refuse to move anywhere,\n * so we check current scroll position before shrinking and then restore it\n * with needed delta.\n */\n\n // this part has to be BEFORE the content size update\n const currentScroll = scrollerRef === window\n ? scrollerRef.scrollY\n : scrollerRef.scrollTop\n const scrollerHeight = scrollerRef === window\n ? scrollerRef.innerHeight\n : scrollerRef.offsetHeight\n const scrollerBottomBorder = currentScroll + scrollerHeight\n\n // BEGIN content size update\n target.style.height = 'auto'\n const newHeight = target.scrollHeight - vertPadding\n target.style.height = `${newHeight}px`\n // END content size update\n\n // We check where the bottom border of form-bottom element is, this uses findOffset\n // to find offset relative to scrollable container (scroller)\n const bottomBottomBorder = bottomRef.offsetHeight + findOffset(bottomRef, scrollerRef).top + bottomBottomPadding\n\n const isBottomObstructed = scrollerBottomBorder < bottomBottomBorder\n const isFormBiggerThanScroller = scrollerHeight < formRef.offsetHeight\n const bottomChangeDelta = bottomBottomBorder - scrollerBottomBorder\n // The intention is basically this;\n // Keep form-bottom always visible so that submit button is in view EXCEPT\n // if form element bigger than scroller and caret isn't at the end, so that\n // if you scroll up and edit middle of text you won't get scrolled back to bottom\n const shouldScrollToBottom = isBottomObstructed &&\n !(isFormBiggerThanScroller &&\n this.$refs.textarea.selectionStart !== this.$refs.textarea.value.length)\n const totalDelta = shouldScrollToBottom ? bottomChangeDelta : 0\n const targetScroll = currentScroll + totalDelta\n\n if (scrollerRef === window) {\n scrollerRef.scroll(0, targetScroll)\n } else {\n scrollerRef.scrollTop = targetScroll\n }\n\n this.$refs['emoji-input'].resize()\n },\n showEmojiPicker () {\n this.$refs['textarea'].focus()\n this.$refs['emoji-input'].triggerShowPicker()\n },\n clearError () {\n this.error = null\n },\n changeVis (visibility) {\n this.newStatus.visibility = visibility\n },\n togglePollForm () {\n this.pollFormVisible = !this.pollFormVisible\n },\n setPoll (poll) {\n this.newStatus.poll = poll\n },\n clearPollForm () {\n if (this.$refs.pollForm) {\n this.$refs.pollForm.clear()\n }\n },\n dismissScopeNotice () {\n this.$store.dispatch('setOption', { name: 'hideScopeNotice', value: true })\n }\n }\n}\n\nexport default PostStatusForm\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./post_status_form.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./post_status_form.js\"\nimport __vue_script__ from \"!!babel-loader!./post_status_form.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-c2ba770c\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./post_status_form.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{ref:\"form\",staticClass:\"post-status-form\"},[_c('form',{attrs:{\"autocomplete\":\"off\"},on:{\"submit\":function($event){$event.preventDefault();return _vm.postStatus(_vm.newStatus)}}},[_c('div',{staticClass:\"form-group\"},[(!_vm.$store.state.users.currentUser.locked && _vm.newStatus.visibility == 'private')?_c('i18n',{staticClass:\"visibility-notice\",attrs:{\"path\":\"post_status.account_not_locked_warning\",\"tag\":\"p\"}},[_c('router-link',{attrs:{\"to\":{ name: 'user-settings' }}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('post_status.account_not_locked_warning_link'))+\"\\n \")])],1):_vm._e(),_vm._v(\" \"),(!_vm.hideScopeNotice && _vm.newStatus.visibility === 'public')?_c('p',{staticClass:\"visibility-notice notice-dismissible\"},[_c('span',[_vm._v(_vm._s(_vm.$t('post_status.scope_notice.public')))]),_vm._v(\" \"),_c('a',{staticClass:\"button-icon dismiss\",on:{\"click\":function($event){$event.preventDefault();return _vm.dismissScopeNotice()}}},[_c('i',{staticClass:\"icon-cancel\"})])]):(!_vm.hideScopeNotice && _vm.newStatus.visibility === 'unlisted')?_c('p',{staticClass:\"visibility-notice notice-dismissible\"},[_c('span',[_vm._v(_vm._s(_vm.$t('post_status.scope_notice.unlisted')))]),_vm._v(\" \"),_c('a',{staticClass:\"button-icon dismiss\",on:{\"click\":function($event){$event.preventDefault();return _vm.dismissScopeNotice()}}},[_c('i',{staticClass:\"icon-cancel\"})])]):(!_vm.hideScopeNotice && _vm.newStatus.visibility === 'private' && _vm.$store.state.users.currentUser.locked)?_c('p',{staticClass:\"visibility-notice notice-dismissible\"},[_c('span',[_vm._v(_vm._s(_vm.$t('post_status.scope_notice.private')))]),_vm._v(\" \"),_c('a',{staticClass:\"button-icon dismiss\",on:{\"click\":function($event){$event.preventDefault();return _vm.dismissScopeNotice()}}},[_c('i',{staticClass:\"icon-cancel\"})])]):(_vm.newStatus.visibility === 'direct')?_c('p',{staticClass:\"visibility-notice\"},[(_vm.safeDMEnabled)?_c('span',[_vm._v(_vm._s(_vm.$t('post_status.direct_warning_to_first_only')))]):_c('span',[_vm._v(_vm._s(_vm.$t('post_status.direct_warning_to_all')))])]):_vm._e(),_vm._v(\" \"),(_vm.newStatus.spoilerText || _vm.alwaysShowSubject)?_c('EmojiInput',{staticClass:\"form-control\",attrs:{\"enable-emoji-picker\":\"\",\"suggest\":_vm.emojiSuggestor},model:{value:(_vm.newStatus.spoilerText),callback:function ($$v) {_vm.$set(_vm.newStatus, \"spoilerText\", $$v)},expression:\"newStatus.spoilerText\"}},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.newStatus.spoilerText),expression:\"newStatus.spoilerText\"}],staticClass:\"form-post-subject\",attrs:{\"type\":\"text\",\"placeholder\":_vm.$t('post_status.content_warning')},domProps:{\"value\":(_vm.newStatus.spoilerText)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.$set(_vm.newStatus, \"spoilerText\", $event.target.value)}}})]):_vm._e(),_vm._v(\" \"),_c('EmojiInput',{ref:\"emoji-input\",staticClass:\"form-control main-input\",attrs:{\"suggest\":_vm.emojiUserSuggestor,\"enable-emoji-picker\":\"\",\"hide-emoji-button\":\"\",\"enable-sticker-picker\":\"\"},on:{\"input\":_vm.onEmojiInputInput,\"sticker-uploaded\":_vm.addMediaFile,\"sticker-upload-failed\":_vm.uploadFailed},model:{value:(_vm.newStatus.status),callback:function ($$v) {_vm.$set(_vm.newStatus, \"status\", $$v)},expression:\"newStatus.status\"}},[_c('textarea',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.newStatus.status),expression:\"newStatus.status\"}],ref:\"textarea\",staticClass:\"form-post-body\",attrs:{\"placeholder\":_vm.$t('post_status.default'),\"rows\":\"1\",\"disabled\":_vm.posting},domProps:{\"value\":(_vm.newStatus.status)},on:{\"keydown\":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,\"enter\",13,$event.key,\"Enter\")){ return null; }if(!$event.metaKey){ return null; }return _vm.postStatus(_vm.newStatus)},\"keyup\":function($event){if(!$event.type.indexOf('key')&&_vm._k($event.keyCode,\"enter\",13,$event.key,\"Enter\")){ return null; }if(!$event.ctrlKey){ return null; }return _vm.postStatus(_vm.newStatus)},\"drop\":_vm.fileDrop,\"dragover\":function($event){$event.preventDefault();return _vm.fileDrag($event)},\"input\":[function($event){if($event.target.composing){ return; }_vm.$set(_vm.newStatus, \"status\", $event.target.value)},_vm.resize],\"compositionupdate\":_vm.resize,\"paste\":_vm.paste}}),_vm._v(\" \"),(_vm.hasStatusLengthLimit)?_c('p',{staticClass:\"character-counter faint\",class:{ error: _vm.isOverLengthLimit }},[_vm._v(\"\\n \"+_vm._s(_vm.charactersLeft)+\"\\n \")]):_vm._e()]),_vm._v(\" \"),_c('div',{staticClass:\"visibility-tray\"},[_c('scope-selector',{attrs:{\"show-all\":_vm.showAllScopes,\"user-default\":_vm.userDefaultScope,\"original-scope\":_vm.copyMessageScope,\"initial-scope\":_vm.newStatus.visibility,\"on-scope-change\":_vm.changeVis}}),_vm._v(\" \"),(_vm.postFormats.length > 1)?_c('div',{staticClass:\"text-format\"},[_c('label',{staticClass:\"select\",attrs:{\"for\":\"post-content-type\"}},[_c('select',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.newStatus.contentType),expression:\"newStatus.contentType\"}],staticClass:\"form-control\",attrs:{\"id\":\"post-content-type\"},on:{\"change\":function($event){var $$selectedVal = Array.prototype.filter.call($event.target.options,function(o){return o.selected}).map(function(o){var val = \"_value\" in o ? o._value : o.value;return val}); _vm.$set(_vm.newStatus, \"contentType\", $event.target.multiple ? $$selectedVal : $$selectedVal[0])}}},_vm._l((_vm.postFormats),function(postFormat){return _c('option',{key:postFormat,domProps:{\"value\":postFormat}},[_vm._v(\"\\n \"+_vm._s(_vm.$t((\"post_status.content_type[\\\"\" + postFormat + \"\\\"]\")))+\"\\n \")])}),0),_vm._v(\" \"),_c('i',{staticClass:\"icon-down-open\"})])]):_vm._e(),_vm._v(\" \"),(_vm.postFormats.length === 1 && _vm.postFormats[0] !== 'text/plain')?_c('div',{staticClass:\"text-format\"},[_c('span',{staticClass:\"only-format\"},[_vm._v(\"\\n \"+_vm._s(_vm.$t((\"post_status.content_type[\\\"\" + (_vm.postFormats[0]) + \"\\\"]\")))+\"\\n \")])]):_vm._e()],1)],1),_vm._v(\" \"),(_vm.pollsAvailable)?_c('poll-form',{ref:\"pollForm\",attrs:{\"visible\":_vm.pollFormVisible},on:{\"update-poll\":_vm.setPoll}}):_vm._e(),_vm._v(\" \"),_c('div',{ref:\"bottom\",staticClass:\"form-bottom\"},[_c('div',{staticClass:\"form-bottom-left\"},[_c('media-upload',{ref:\"mediaUpload\",staticClass:\"media-upload-icon\",attrs:{\"drop-files\":_vm.dropFiles},on:{\"uploading\":_vm.disableSubmit,\"uploaded\":_vm.addMediaFile,\"upload-failed\":_vm.uploadFailed}}),_vm._v(\" \"),_c('div',{staticClass:\"emoji-icon\"},[_c('i',{staticClass:\"icon-smile btn btn-default\",attrs:{\"title\":_vm.$t('emoji.add_emoji')},on:{\"click\":_vm.showEmojiPicker}})]),_vm._v(\" \"),(_vm.pollsAvailable)?_c('div',{staticClass:\"poll-icon\",class:{ selected: _vm.pollFormVisible }},[_c('i',{staticClass:\"icon-chart-bar btn btn-default\",attrs:{\"title\":_vm.$t('polls.add_poll')},on:{\"click\":_vm.togglePollForm}})]):_vm._e()],1),_vm._v(\" \"),(_vm.posting)?_c('button',{staticClass:\"btn btn-default\",attrs:{\"disabled\":\"\"}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('post_status.posting'))+\"\\n \")]):(_vm.isOverLengthLimit)?_c('button',{staticClass:\"btn btn-default\",attrs:{\"disabled\":\"\"}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('general.submit'))+\"\\n \")]):_c('button',{staticClass:\"btn btn-default\",attrs:{\"disabled\":_vm.submitDisabled,\"type\":\"submit\"}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('general.submit'))+\"\\n \")])]),_vm._v(\" \"),(_vm.error)?_c('div',{staticClass:\"alert error\"},[_vm._v(\"\\n Error: \"+_vm._s(_vm.error)+\"\\n \"),_c('i',{staticClass:\"button-icon icon-cancel\",on:{\"click\":_vm.clearError}})]):_vm._e(),_vm._v(\" \"),_c('div',{staticClass:\"attachments\"},_vm._l((_vm.newStatus.files),function(file){return _c('div',{key:file.url,staticClass:\"media-upload-wrapper\"},[_c('i',{staticClass:\"fa button-icon icon-cancel\",on:{\"click\":function($event){return _vm.removeMediaFile(file)}}}),_vm._v(\" \"),_c('div',{staticClass:\"media-upload-container attachment\"},[(_vm.type(file) === 'image')?_c('img',{staticClass:\"thumbnail media-upload\",attrs:{\"src\":file.url}}):_vm._e(),_vm._v(\" \"),(_vm.type(file) === 'video')?_c('video',{attrs:{\"src\":file.url,\"controls\":\"\"}}):_vm._e(),_vm._v(\" \"),(_vm.type(file) === 'audio')?_c('audio',{attrs:{\"src\":file.url,\"controls\":\"\"}}):_vm._e(),_vm._v(\" \"),(_vm.type(file) === 'unknown')?_c('a',{attrs:{\"href\":file.url}},[_vm._v(_vm._s(file.url))]):_vm._e()])])}),0),_vm._v(\" \"),(_vm.newStatus.files.length > 0)?_c('div',{staticClass:\"upload_settings\"},[_c('Checkbox',{model:{value:(_vm.newStatus.nsfw),callback:function ($$v) {_vm.$set(_vm.newStatus, \"nsfw\", $$v)},expression:\"newStatus.nsfw\"}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('post_status.attachments_sensitive'))+\"\\n \")])],1):_vm._e()],1)])}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","const StillImage = {\n props: [\n 'src',\n 'referrerpolicy',\n 'mimetype',\n 'imageLoadError',\n 'imageLoadHandler'\n ],\n data () {\n return {\n stopGifs: this.$store.getters.mergedConfig.stopGifs\n }\n },\n computed: {\n animated () {\n return this.stopGifs && (this.mimetype === 'image/gif' || this.src.endsWith('.gif'))\n }\n },\n methods: {\n onLoad () {\n this.imageLoadHandler && this.imageLoadHandler(this.$refs.src)\n const canvas = this.$refs.canvas\n if (!canvas) return\n const width = this.$refs.src.naturalWidth\n const height = this.$refs.src.naturalHeight\n canvas.width = width\n canvas.height = height\n canvas.getContext('2d').drawImage(this.$refs.src, 0, 0, width, height)\n },\n onError () {\n this.imageLoadError && this.imageLoadError()\n }\n }\n}\n\nexport default StillImage\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!../../../node_modules/vue-loader/lib/selector?type=styles&index=0!./still-image.vue\")\n}\n/* script */\nexport * from \"!!babel-loader!./still-image.js\"\nimport __vue_script__ from \"!!babel-loader!./still-image.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-1bc509fc\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./still-image.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"still-image\",class:{ animated: _vm.animated }},[(_vm.animated)?_c('canvas',{ref:\"canvas\"}):_vm._e(),_vm._v(\" \"),_c('img',{key:_vm.src,ref:\"src\",attrs:{\"src\":_vm.src,\"referrerpolicy\":_vm.referrerpolicy},on:{\"load\":_vm.onLoad,\"error\":_vm.onError}})])}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","\n\n\n","/* script */\nexport * from \"!!babel-loader!../../../node_modules/vue-loader/lib/selector?type=script&index=0!./timeago.vue\"\nimport __vue_script__ from \"!!babel-loader!../../../node_modules/vue-loader/lib/selector?type=script&index=0!./timeago.vue\"\n/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-ac499830\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./timeago.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = null\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('time',{attrs:{\"datetime\":_vm.time,\"title\":_vm.localeDateString}},[_vm._v(\"\\n \"+_vm._s(_vm.$t(_vm.relativeTime.key, [_vm.relativeTime.num]))+\"\\n\")])}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","const fileSizeFormat = (num) => {\n var exponent\n var unit\n var units = ['B', 'KiB', 'MiB', 'GiB', 'TiB']\n if (num < 1) {\n return num + ' ' + units[0]\n }\n\n exponent = Math.min(Math.floor(Math.log(num) / Math.log(1024)), units.length - 1)\n num = (num / Math.pow(1024, exponent)).toFixed(2) * 1\n unit = units[exponent]\n return { num: num, unit: unit }\n}\nconst fileSizeFormatService = {\n fileSizeFormat\n}\nexport default fileSizeFormatService\n","import { debounce } from 'lodash'\n/**\n * suggest - generates a suggestor function to be used by emoji-input\n * data: object providing source information for specific types of suggestions:\n * data.emoji - optional, an array of all emoji available i.e.\n * (state.instance.emoji + state.instance.customEmoji)\n * data.users - optional, an array of all known users\n * updateUsersList - optional, a function to search and append to users\n *\n * Depending on data present one or both (or none) can be present, so if field\n * doesn't support user linking you can just provide only emoji.\n */\n\nconst debounceUserSearch = debounce((data, input) => {\n data.updateUsersList(input)\n}, 500, { leading: true, trailing: false })\n\nexport default data => input => {\n const firstChar = input[0]\n if (firstChar === ':' && data.emoji) {\n return suggestEmoji(data.emoji)(input)\n }\n if (firstChar === '@' && data.users) {\n return suggestUsers(data)(input)\n }\n return []\n}\n\nexport const suggestEmoji = emojis => input => {\n const noPrefix = input.toLowerCase().substr(1)\n return emojis\n .filter(({ displayText }) => displayText.toLowerCase().match(noPrefix))\n .sort((a, b) => {\n let aScore = 0\n let bScore = 0\n\n // An exact match always wins\n aScore += a.displayText.toLowerCase() === noPrefix ? 200 : 0\n bScore += b.displayText.toLowerCase() === noPrefix ? 200 : 0\n\n // Prioritize custom emoji a lot\n aScore += a.imageUrl ? 100 : 0\n bScore += b.imageUrl ? 100 : 0\n\n // Prioritize prefix matches somewhat\n aScore += a.displayText.toLowerCase().startsWith(noPrefix) ? 10 : 0\n bScore += b.displayText.toLowerCase().startsWith(noPrefix) ? 10 : 0\n\n // Sort by length\n aScore -= a.displayText.length\n bScore -= b.displayText.length\n\n // Break ties alphabetically\n const alphabetically = a.displayText > b.displayText ? 0.5 : -0.5\n\n return bScore - aScore + alphabetically\n })\n}\n\nexport const suggestUsers = data => input => {\n const noPrefix = input.toLowerCase().substr(1)\n const users = data.users\n\n const newUsers = users.filter(\n user =>\n user.screen_name.toLowerCase().startsWith(noPrefix) ||\n user.name.toLowerCase().startsWith(noPrefix)\n\n /* taking only 20 results so that sorting is a bit cheaper, we display\n * only 5 anyway. could be inaccurate, but we ideally we should query\n * backend anyway\n */\n ).slice(0, 20).sort((a, b) => {\n let aScore = 0\n let bScore = 0\n\n // Matches on screen name (i.e. user@instance) makes a priority\n aScore += a.screen_name.toLowerCase().startsWith(noPrefix) ? 2 : 0\n bScore += b.screen_name.toLowerCase().startsWith(noPrefix) ? 2 : 0\n\n // Matches on name takes second priority\n aScore += a.name.toLowerCase().startsWith(noPrefix) ? 1 : 0\n bScore += b.name.toLowerCase().startsWith(noPrefix) ? 1 : 0\n\n const diff = (bScore - aScore) * 10\n\n // Then sort alphabetically\n const nameAlphabetically = a.name > b.name ? 1 : -1\n const screenNameAlphabetically = a.screen_name > b.screen_name ? 1 : -1\n\n return diff + nameAlphabetically + screenNameAlphabetically\n /* eslint-disable camelcase */\n }).map(({ screen_name, name, profile_image_url_original }) => ({\n displayText: screen_name,\n detailText: name,\n imageUrl: profile_image_url_original,\n replacement: '@' + screen_name + ' '\n }))\n\n // BE search users if there are no matches\n if (newUsers.length === 0 && data.updateUsersList) {\n debounceUserSearch(data, noPrefix)\n }\n return newUsers\n /* eslint-enable camelcase */\n}\n","import { map } from 'lodash'\nimport apiService from '../api/api.service.js'\n\nconst postStatus = ({ store, status, spoilerText, visibility, sensitive, poll, media = [], inReplyToStatusId = undefined, contentType = 'text/plain' }) => {\n const mediaIds = map(media, 'id')\n\n return apiService.postStatus({\n credentials: store.state.users.currentUser.credentials,\n status,\n spoilerText,\n visibility,\n sensitive,\n mediaIds,\n inReplyToStatusId,\n contentType,\n poll })\n .then((data) => {\n if (!data.error) {\n store.dispatch('addNewStatuses', {\n statuses: [data],\n timeline: 'friends',\n showImmediately: true,\n noIdUpdate: true // To prevent missing notices on next pull.\n })\n }\n return data\n })\n .catch((err) => {\n return {\n error: err.message\n }\n })\n}\n\nconst uploadMedia = ({ store, formData }) => {\n const credentials = store.state.users.currentUser.credentials\n\n return apiService.uploadMedia({ credentials, formData })\n}\n\nconst statusPosterService = {\n postStatus,\n uploadMedia\n}\n\nexport default statusPosterService\n","export const findOffset = (child, parent, { top = 0, left = 0 } = {}, ignorePadding = true) => {\n const result = {\n top: top + child.offsetTop,\n left: left + child.offsetLeft\n }\n if (!ignorePadding && child !== window) {\n const { topPadding, leftPadding } = findPadding(child)\n result.top += ignorePadding ? 0 : topPadding\n result.left += ignorePadding ? 0 : leftPadding\n }\n\n if (child.offsetParent && (parent === window || parent.contains(child.offsetParent) || parent === child.offsetParent)) {\n return findOffset(child.offsetParent, parent, result, false)\n } else {\n if (parent !== window) {\n const { topPadding, leftPadding } = findPadding(parent)\n result.top += topPadding\n result.left += leftPadding\n }\n return result\n }\n}\n\nconst findPadding = (el) => {\n const topPaddingStr = window.getComputedStyle(el)['padding-top']\n const topPadding = Number(topPaddingStr.substring(0, topPaddingStr.length - 2))\n const leftPaddingStr = window.getComputedStyle(el)['padding-left']\n const leftPadding = Number(leftPaddingStr.substring(0, leftPaddingStr.length - 2))\n\n return { topPadding, leftPadding }\n}\n","import { reduce, find } from 'lodash'\n\nexport const replaceWord = (str, toReplace, replacement) => {\n return str.slice(0, toReplace.start) + replacement + str.slice(toReplace.end)\n}\n\nexport const wordAtPosition = (str, pos) => {\n const words = splitIntoWords(str)\n const wordsWithPosition = addPositionToWords(words)\n\n return find(wordsWithPosition, ({ start, end }) => start <= pos && end > pos)\n}\n\nexport const addPositionToWords = (words) => {\n return reduce(words, (result, word) => {\n const data = {\n word,\n start: 0,\n end: word.length\n }\n\n if (result.length > 0) {\n const previous = result.pop()\n\n data.start += previous.end\n data.end += previous.end\n\n result.push(previous)\n }\n\n result.push(data)\n\n return result\n }, [])\n}\n\nexport const splitIntoWords = (str) => {\n // Split at word boundaries\n const regex = /\\b/\n const triggers = /[@#:]+$/\n\n let split = str.split(regex)\n\n // Add trailing @ and # to the following word.\n const words = reduce(split, (result, word) => {\n if (result.length > 0) {\n let previous = result.pop()\n const matches = previous.match(triggers)\n if (matches) {\n previous = previous.replace(triggers, '')\n word = matches[0] + word\n }\n result.push(previous)\n }\n result.push(word)\n\n return result\n }, [])\n\n return words\n}\n\nconst completion = {\n wordAtPosition,\n addPositionToWords,\n splitIntoWords,\n replaceWord\n}\n\nexport default completion\n","import Checkbox from '../checkbox/checkbox.vue'\n\n// At widest, approximately 20 emoji are visible in a row,\n// loading 3 rows, could be overkill for narrow picker\nconst LOAD_EMOJI_BY = 60\n\n// When to start loading new batch emoji, in pixels\nconst LOAD_EMOJI_MARGIN = 64\n\nconst filterByKeyword = (list, keyword = '') => {\n return list.filter(x => x.displayText.includes(keyword))\n}\n\nconst EmojiPicker = {\n props: {\n enableStickerPicker: {\n required: false,\n type: Boolean,\n default: false\n }\n },\n data () {\n return {\n keyword: '',\n activeGroup: 'custom',\n showingStickers: false,\n groupsScrolledClass: 'scrolled-top',\n keepOpen: false,\n customEmojiBufferSlice: LOAD_EMOJI_BY,\n customEmojiTimeout: null,\n customEmojiLoadAllConfirmed: false\n }\n },\n components: {\n StickerPicker: () => import('../sticker_picker/sticker_picker.vue'),\n Checkbox\n },\n methods: {\n onStickerUploaded (e) {\n this.$emit('sticker-uploaded', e)\n },\n onStickerUploadFailed (e) {\n this.$emit('sticker-upload-failed', e)\n },\n onEmoji (emoji) {\n const value = emoji.imageUrl ? `:${emoji.displayText}:` : emoji.replacement\n this.$emit('emoji', { insertion: value, keepOpen: this.keepOpen })\n },\n onScroll (e) {\n const target = (e && e.target) || this.$refs['emoji-groups']\n this.updateScrolledClass(target)\n this.scrolledGroup(target)\n this.triggerLoadMore(target)\n },\n highlight (key) {\n const ref = this.$refs['group-' + key]\n const top = ref[0].offsetTop\n this.setShowStickers(false)\n this.activeGroup = key\n this.$nextTick(() => {\n this.$refs['emoji-groups'].scrollTop = top + 1\n })\n },\n updateScrolledClass (target) {\n if (target.scrollTop <= 5) {\n this.groupsScrolledClass = 'scrolled-top'\n } else if (target.scrollTop >= target.scrollTopMax - 5) {\n this.groupsScrolledClass = 'scrolled-bottom'\n } else {\n this.groupsScrolledClass = 'scrolled-middle'\n }\n },\n triggerLoadMore (target) {\n const ref = this.$refs['group-end-custom'][0]\n if (!ref) return\n const bottom = ref.offsetTop + ref.offsetHeight\n\n const scrollerBottom = target.scrollTop + target.clientHeight\n const scrollerTop = target.scrollTop\n const scrollerMax = target.scrollHeight\n\n // Loads more emoji when they come into view\n const approachingBottom = bottom - scrollerBottom < LOAD_EMOJI_MARGIN\n // Always load when at the very top in case there's no scroll space yet\n const atTop = scrollerTop < 5\n // Don't load when looking at unicode category or at the very bottom\n const bottomAboveViewport = bottom < scrollerTop || scrollerBottom === scrollerMax\n if (!bottomAboveViewport && (approachingBottom || atTop)) {\n this.loadEmoji()\n }\n },\n scrolledGroup (target) {\n const top = target.scrollTop + 5\n this.$nextTick(() => {\n this.emojisView.forEach(group => {\n const ref = this.$refs['group-' + group.id]\n if (ref[0].offsetTop <= top) {\n this.activeGroup = group.id\n }\n })\n })\n },\n loadEmoji () {\n const allLoaded = this.customEmojiBuffer.length === this.filteredEmoji.length\n\n if (allLoaded) {\n return\n }\n\n this.customEmojiBufferSlice += LOAD_EMOJI_BY\n },\n startEmojiLoad (forceUpdate = false) {\n if (!forceUpdate) {\n this.keyword = ''\n }\n this.$nextTick(() => {\n this.$refs['emoji-groups'].scrollTop = 0\n })\n const bufferSize = this.customEmojiBuffer.length\n const bufferPrefilledAll = bufferSize === this.filteredEmoji.length\n if (bufferPrefilledAll && !forceUpdate) {\n return\n }\n this.customEmojiBufferSlice = LOAD_EMOJI_BY\n },\n toggleStickers () {\n this.showingStickers = !this.showingStickers\n },\n setShowStickers (value) {\n this.showingStickers = value\n }\n },\n watch: {\n keyword () {\n this.customEmojiLoadAllConfirmed = false\n this.onScroll()\n this.startEmojiLoad(true)\n }\n },\n computed: {\n activeGroupView () {\n return this.showingStickers ? '' : this.activeGroup\n },\n stickersAvailable () {\n if (this.$store.state.instance.stickers) {\n return this.$store.state.instance.stickers.length > 0\n }\n return 0\n },\n filteredEmoji () {\n return filterByKeyword(\n this.$store.state.instance.customEmoji || [],\n this.keyword\n )\n },\n customEmojiBuffer () {\n return this.filteredEmoji.slice(0, this.customEmojiBufferSlice)\n },\n emojis () {\n const standardEmojis = this.$store.state.instance.emoji || []\n const customEmojis = this.customEmojiBuffer\n\n return [\n {\n id: 'custom',\n text: this.$t('emoji.custom'),\n icon: 'icon-smile',\n emojis: customEmojis\n },\n {\n id: 'standard',\n text: this.$t('emoji.unicode'),\n icon: 'icon-picture',\n emojis: filterByKeyword(standardEmojis, this.keyword)\n }\n ]\n },\n emojisView () {\n return this.emojis.filter(value => value.emojis.length > 0)\n },\n stickerPickerEnabled () {\n return (this.$store.state.instance.stickers || []).length !== 0\n }\n }\n}\n\nexport default EmojiPicker\n","function injectStyle (context) {\n require(\"!!vue-style-loader!css-loader?minimize!../../../node_modules/vue-loader/lib/style-compiler/index?{\\\"optionsId\\\":\\\"0\\\",\\\"vue\\\":true,\\\"scoped\\\":false,\\\"sourceMap\\\":false}!sass-loader!./emoji_picker.scss\")\n}\n/* script */\nexport * from \"!!babel-loader!./emoji_picker.js\"\nimport __vue_script__ from \"!!babel-loader!./emoji_picker.js\"/* template */\nimport {render as __vue_render__, staticRenderFns as __vue_static_render_fns__} from \"!!../../../node_modules/vue-loader/lib/template-compiler/index?{\\\"id\\\":\\\"data-v-47d21b3b\\\",\\\"hasScoped\\\":false,\\\"optionsId\\\":\\\"0\\\",\\\"buble\\\":{\\\"transforms\\\":{}}}!../../../node_modules/vue-loader/lib/selector?type=template&index=0!./emoji_picker.vue\"\n/* template functional */\nvar __vue_template_functional__ = false\n/* styles */\nvar __vue_styles__ = injectStyle\n/* scopeId */\nvar __vue_scopeId__ = null\n/* moduleIdentifier (server only) */\nvar __vue_module_identifier__ = null\nimport normalizeComponent from \"!../../../node_modules/vue-loader/lib/runtime/component-normalizer\"\nvar Component = normalizeComponent(\n __vue_script__,\n __vue_render__,\n __vue_static_render_fns__,\n __vue_template_functional__,\n __vue_styles__,\n __vue_scopeId__,\n __vue_module_identifier__\n)\n\nexport default Component.exports\n","var render = function () {var _vm=this;var _h=_vm.$createElement;var _c=_vm._self._c||_h;return _c('div',{staticClass:\"emoji-picker panel panel-default panel-body\"},[_c('div',{staticClass:\"heading\"},[_c('span',{staticClass:\"emoji-tabs\"},_vm._l((_vm.emojis),function(group){return _c('span',{key:group.id,staticClass:\"emoji-tabs-item\",class:{\n active: _vm.activeGroupView === group.id,\n disabled: group.emojis.length === 0\n },attrs:{\"title\":group.text},on:{\"click\":function($event){$event.preventDefault();return _vm.highlight(group.id)}}},[_c('i',{class:group.icon})])}),0),_vm._v(\" \"),(_vm.stickerPickerEnabled)?_c('span',{staticClass:\"additional-tabs\"},[_c('span',{staticClass:\"stickers-tab-icon additional-tabs-item\",class:{active: _vm.showingStickers},attrs:{\"title\":_vm.$t('emoji.stickers')},on:{\"click\":function($event){$event.preventDefault();return _vm.toggleStickers($event)}}},[_c('i',{staticClass:\"icon-star\"})])]):_vm._e()]),_vm._v(\" \"),_c('div',{staticClass:\"content\"},[_c('div',{staticClass:\"emoji-content\",class:{hidden: _vm.showingStickers}},[_c('div',{staticClass:\"emoji-search\"},[_c('input',{directives:[{name:\"model\",rawName:\"v-model\",value:(_vm.keyword),expression:\"keyword\"}],staticClass:\"form-control\",attrs:{\"type\":\"text\",\"placeholder\":_vm.$t('emoji.search_emoji')},domProps:{\"value\":(_vm.keyword)},on:{\"input\":function($event){if($event.target.composing){ return; }_vm.keyword=$event.target.value}}})]),_vm._v(\" \"),_c('div',{ref:\"emoji-groups\",staticClass:\"emoji-groups\",class:_vm.groupsScrolledClass,on:{\"scroll\":_vm.onScroll}},_vm._l((_vm.emojisView),function(group){return _c('div',{key:group.id,staticClass:\"emoji-group\"},[_c('h6',{ref:'group-' + group.id,refInFor:true,staticClass:\"emoji-group-title\"},[_vm._v(\"\\n \"+_vm._s(group.text)+\"\\n \")]),_vm._v(\" \"),_vm._l((group.emojis),function(emoji){return _c('span',{key:group.id + emoji.displayText,staticClass:\"emoji-item\",attrs:{\"title\":emoji.displayText},on:{\"click\":function($event){$event.stopPropagation();$event.preventDefault();return _vm.onEmoji(emoji)}}},[(!emoji.imageUrl)?_c('span',[_vm._v(_vm._s(emoji.replacement))]):_c('img',{attrs:{\"src\":emoji.imageUrl}})])}),_vm._v(\" \"),_c('span',{ref:'group-end-' + group.id,refInFor:true})],2)}),0),_vm._v(\" \"),_c('div',{staticClass:\"keep-open\"},[_c('Checkbox',{model:{value:(_vm.keepOpen),callback:function ($$v) {_vm.keepOpen=$$v},expression:\"keepOpen\"}},[_vm._v(\"\\n \"+_vm._s(_vm.$t('emoji.keep_open'))+\"\\n \")])],1)]),_vm._v(\" \"),(_vm.showingStickers)?_c('div',{staticClass:\"stickers-content\"},[_c('sticker-picker',{on:{\"uploaded\":_vm.onStickerUploaded,\"upload-failed\":_vm.onStickerUploadFailed}})],1):_vm._e()])])}\nvar staticRenderFns = []\nexport { render, staticRenderFns }","import Completion from '../../services/completion/completion.js'\nimport EmojiPicker from '../emoji_picker/emoji_picker.vue'\nimport { take } from 'lodash'\nimport { findOffset } from '../../services/offset_finder/offset_finder.service.js'\n\n/**\n * EmojiInput - augmented inputs for emoji and autocomplete support in inputs\n * without having to give up the comfort of and