diff --git a/CHANGELOG.md b/CHANGELOG.md
index 591bcbe4c..5b7e5c9a1 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,8 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
## [unreleased]
+### Security
+- Mastodon API: Fix display names not being sanitized
### Added
- Add a generic settings store for frontends / clients to use.
- Explicit addressing option for posting.
diff --git a/config/config.exs b/config/config.exs
index 7f46a8755..3962ac019 100644
--- a/config/config.exs
+++ b/config/config.exs
@@ -442,6 +442,8 @@
opts: [
scheme: true,
extra: true,
+ # TODO: Set to :no_scheme when it works properly
+ validate_tld: true,
class: false,
strip_prefix: false,
new_window: false,
diff --git a/lib/mix/tasks/pleroma/ecto/ecto.ex b/lib/mix/tasks/pleroma/ecto/ecto.ex
new file mode 100644
index 000000000..af09cb289
--- /dev/null
+++ b/lib/mix/tasks/pleroma/ecto/ecto.ex
@@ -0,0 +1,40 @@
+# Pleroma: A lightweight social networking server
+# Copyright © 2017-2018 Pleroma Authors
20},longSubject:function(){return this.status.summary.length>900},isReply:function(){return!(!this.status.in_reply_to_status_id||!this.status.in_reply_to_user_id)},replyToName:function(){if(this.status.in_reply_to_screen_name)return this.status.in_reply_to_screen_name;var e=this.$store.getters.findUser(this.status.in_reply_to_user_id);return e&&e.screen_name},hideReply:function(){if("all"===this.$store.state.config.replyVisibility)return!1;if(this.inConversation||!this.isReply)return!1;if(this.status.user.id===this.$store.state.users.currentUser.id)return!1;if("retweet"===this.status.type)return!1;for(var e="following"===this.$store.state.config.replyVisibility,t=0;t for paragraphs, GS uses 20\n },\n longSubject () {\n return this.status.summary.length > 900\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.$store.state.config.replyVisibility === 'all') {\n return false\n }\n if (this.inConversation || !this.isReply) {\n return false\n }\n if (this.status.user.id === this.$store.state.users.currentUser.id) {\n return false\n }\n if (this.status.type === 'retweet') {\n return false\n }\n var checkFollowing = this.$store.state.config.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 if (checkFollowing && this.$store.getters.findUser(this.status.attentions[i].id).following) {\n return false\n }\n if (this.status.attentions[i].id === this.$store.state.users.currentUser.id) {\n return false\n }\n }\n return this.status.attentions.length > 0\n },\n hideSubjectStatus () {\n if (this.tallStatus && !this.localCollapseSubjectDefault) {\n return false\n }\n return !this.expandingSubject && this.status.summary\n },\n hideTallStatus () {\n if (this.status.summary && this.localCollapseSubjectDefault) {\n return false\n }\n if (this.showingTall) {\n return false\n }\n return this.tallStatus\n },\n showingMore () {\n return (this.tallStatus && this.showingTall) || (this.status.summary && 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 replySubject () {\n if (!this.status.summary) return ''\n const decodedSummary = unescape(this.status.summary)\n const behavior = typeof this.$store.state.config.subjectLineBehavior === 'undefined'\n ? this.$store.state.instance.subjectLineBehavior\n : this.$store.state.config.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 attachmentSize () {\n if ((this.$store.state.config.hideAttachments && !this.inConversation) ||\n (this.$store.state.config.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.$store.state.config.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 maxThumbnails () {\n return this.$store.state.config.maxThumbnails\n },\n contentHtml () {\n if (!this.status.summary_html) {\n return this.status.statusnet_html\n }\n return this.status.summary_html + '
"+this.status.statusnet_html:this.status.statusnet_html},combinedFavsAndRepeatsUsers:function(){var e=[].concat(this.statusFromGlobalRepository.favoritedBy,this.statusFromGlobalRepository.rebloggedBy);return(0,a.default)(e,"id")},ownStatus:function(){return this.status.user.id===this.$store.state.users.currentUser.id},tags:function(){return this.status.tags.filter(function(e){return e.hasOwnProperty("name")}).map(function(e){return e.name}).join(" ")}},components:{Attachment:r.default,FavoriteButton:l.default,RetweetButton:c.default,ExtraButtons:d.default,PostStatusForm:p.default,Poll:u.default,UserCard:f.default,UserAvatar:m.default,Gallery:h.default,LinkPreview:_.default,AvatarList:v.default,Timeago:g.default},methods:{visibilityIcon:function(e){switch(e){case"private":return"icon-lock";case"unlisted":return"icon-lock-open-alt";case"direct":return"icon-mail-alt";default:return"icon-globe"}},showError:function(e){this.error=e},clearError:function(){this.error=void 0},linkClicked:function(e){var t=e.target;if("SPAN"===t.tagName&&(t=t.parentNode),"A"===t.tagName){if(t.className.match(/mention/)){var i=t.href,a=this.status.attentions.find(function(e){return(0,k.mentionMatchesUrl)(e,i)});if(a){e.stopPropagation(),e.preventDefault();var o=this.generateUserProfileLink(a.id,a.screen_name);return void this.$router.push(o)}}if(t.className.match(/hashtag/)){var n=(0,k.extractTagFromUrl)(t.href);if(n){var s=this.generateTagLink(n);return void this.$router.push(s)}}window.open(t.href,"_blank")}},toggleReplying:function(){this.replying=!this.replying},gotoOriginal:function(e){this.inConversation&&this.$emit("goto",e)},toggleExpanded:function(){this.$emit("toggleExpanded")},toggleMute:function(){this.unmuted=!this.unmuted},toggleUserExpanded:function(){this.userExpanded=!this.userExpanded},toggleShowMore:function(){this.showingTall?this.showingTall=!1:this.expandingSubject&&this.status.summary?this.expandingSubject=!1:this.hideTallStatus?this.showingTall=!0:this.hideSubjectStatus&&this.status.summary&&(this.expandingSubject=!0)},replyEnter:function(e,t){var i=this;this.showPreview=!0;var a=e,o=this.$store.state.statuses.allStatuses;this.preview?this.preview.id!==a&&(this.preview=(0,n.default)(o,{id:a})):(this.preview=(0,n.default)(o,{id:a}),this.preview||this.$store.state.api.backendInteractor.fetchStatus({id:e}).then(function(e){i.preview=e}))},replyLeave:function(){this.showPreview=!1},generateUserProfileLink:function(e,t){return(0,b.default)(e,t,this.$store.state.instance.restrictedNicknames)},generateTagLink:function(e){return"/tag/"+e},setMedia:function(){var e=this,t="hide"===this.attachmentSize?this.status.attachments:this.galleryAttachments;return function(){return e.$store.dispatch("setMedia",t)}}},watch:{highlight:function(e){if(this.status.id===e){var t=this.$el.getBoundingClientRect();t.top<100?window.scrollBy(0,t.top-100):t.height>=window.innerHeight-50?window.scrollBy(0,t.top-100):t.bottom>window.innerHeight-50&&window.scrollBy(0,t.bottom-window.innerHeight+50)}}},filters:{capitalize:function(e){return e.charAt(0).toUpperCase()+e.slice(1)}}};t.default=C},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a=r(i(227)),o=r(i(403)),n=r(i(697)),s=r(i(73));function r(e){return e&&e.__esModule?e:{default:e}}var l={props:["attachment","nsfw","statusId","size","allowPlay","setMedia"],data:function(){return{nsfwImage:this.$store.state.instance.nsfwCensorImage||n.default,hideNsfwLocal:this.$store.state.config.hideNsfw,preloadImage:this.$store.state.config.preloadImage,loading:!1,img:"image"===s.default.fileType(this.attachment.mimetype)&&document.createElement("img"),modalOpen:!1,showHidden:!1}},components:{StillImage:a.default,VideoAttachment:o.default},computed:{usePlaceHolder:function(){return"hide"===this.size||"unknown"===this.type},referrerpolicy:function(){return this.$store.state.instance.mediaProxyAvailable?"":"no-referrer"},type:function(){return s.default.fileType(this.attachment.mimetype)},hidden:function(){return this.nsfw&&this.hideNsfwLocal&&!this.showHidden},isEmpty:function(){return"html"===this.type&&!this.attachment.oembed||"unknown"===this.type},isSmall:function(){return"small"===this.size},fullwidth:function(){return"html"===this.type||"audio"===this.type}},methods:{linkClicked:function(e){var t=e.target;"A"===t.tagName&&window.open(t.href,"_blank")},openModal:function(e){var t=this.$store.state.config.playVideosInModal?["image","video"]:["image"];(s.default.fileMatchesSomeType(t,this.attachment)||this.usePlaceHolder)&&(e.stopPropagation(),e.preventDefault(),this.setMedia(),this.$store.dispatch("setCurrent",this.attachment))},toggleHidden:function(e){var t=this;!this.$store.state.config.useOneClickNsfw||this.showHidden?this.img&&!this.preloadImage?this.img.onload?this.img.onload():(this.loading=!0,this.img.src=this.attachment.url,this.img.onload=function(){t.loading=!1,t.showHidden=!t.showHidden}):this.showHidden=!this.showHidden:this.openModal(e)}}};t.default=l},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.default={props:["src","referrerpolicy","mimetype","imageLoadError"],data:function(){return{stopGifs:this.$store.state.config.stopGifs}},computed:{animated:function(){return this.stopGifs&&("image/gif"===this.mimetype||this.src.endsWith(".gif"))}},methods:{onLoad:function(){var e=this.$refs.canvas;if(e){var t=this.$refs.src.naturalWidth,i=this.$refs.src.naturalHeight;e.width=t,e.height=i,e.getContext("2d").drawImage(this.$refs.src,0,0,t,i)}},onError:function(){this.imageLoadError&&this.imageLoadError()}}}},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});t.default={props:["attachment","controls"],data:function(){return{loopVideo:this.$store.state.config.loopVideo}},methods:{onVideoDataLoad:function(e){var t=e.srcElement||e.target;void 0!==t.webkitAudioDecodedByteCount?t.webkitAudioDecodedByteCount>0&&(this.loopVideo=this.loopVideo&&!this.$store.state.config.loopVideoSilentOnly):void 0!==t.mozHasAudio?t.mozHasAudio&&(this.loopVideo=this.loopVideo&&!this.$store.state.config.loopVideoSilentOnly):void 0!==t.audioTracks&&t.audioTracks.length>0&&(this.loopVideo=this.loopVideo&&!this.$store.state.config.loopVideoSilentOnly)}}}},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a={props:["status","loggedIn"],data:function(){return{hidePostStatsLocal:void 0===this.$store.state.config.hidePostStats?this.$store.state.instance.hidePostStats:this.$store.state.config.hidePostStats,animated:!1}},methods:{favorite:function(){var e=this;this.status.favorited?this.$store.dispatch("unfavorite",{id:this.status.id}):this.$store.dispatch("favorite",{id:this.status.id}),this.animated=!0,setTimeout(function(){e.animated=!1},500)}},computed:{classes:function(){return{"icon-star-empty":!this.status.favorited,"icon-star":this.status.favorited,"animate-spin":this.animated}}}};t.default=a},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a={props:["status","loggedIn","visibility"],data:function(){return{hidePostStatsLocal:void 0===this.$store.state.config.hidePostStats?this.$store.state.instance.hidePostStats:this.$store.state.config.hidePostStats,animated:!1}},methods:{retweet:function(){var e=this;this.status.repeated?this.$store.dispatch("unretweet",{id:this.status.id}):this.$store.dispatch("retweet",{id:this.status.id}),this.animated=!0,setTimeout(function(){e.animated=!1},500)}},computed:{classes:function(){return{retweeted:this.status.repeated,"retweeted-empty":!this.status.repeated,"animate-spin":this.animated}}}};t.default=a},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a=s(i(22)),o=s(i(379)),n=s(i(228));function s(e){return e&&e.__esModule?e:{default:e}}t.default={name:"Poll",props:["poll","statusId"],components:{Timeago:n.default},data:function(){return{loading:!1,choices:[],refreshInterval:null}},created:function(){this.refreshInterval=setTimeout(this.refreshPoll,3e4),this.choices=this.poll.options.map(function(e){return!1})},destroyed:function(){clearTimeout(this.refreshInterval)},computed:{expired:function(){return Date.now()>Date.parse(this.poll.expires_at)},loggedIn:function(){return this.$store.state.users.currentUser},showResults:function(){return this.poll.voted||this.expired||!this.loggedIn},totalVotesCount:function(){return this.poll.votes_count},expiresAt:function(){return Date.parse(this.poll.expires_at).toLocaleString()},containerClass:function(){return{loading:this.loading}},choiceIndices:function(){return this.choices.map(function(e,t){return e&&t}).filter(function(e){return"number"==typeof e})},isDisabled:function(){var e=0===this.choiceIndices.length;return this.loading||e}},methods:{refreshPoll:function(){this.expired||(this.fetchPoll(),this.refreshInterval=setTimeout(this.refreshPoll,3e4))},percentageForOption:function(e){return 0===this.totalVotesCount?0:Math.round(e/this.totalVotesCount*100)},resultTitle:function(e){return e.votes_count+"/"+this.totalVotesCount+" "+this.$t("polls.votes")},fetchPoll:function(){this.$store.dispatch("refreshPoll",{id:this.statusId,pollId:this.poll.id})},activateOption:function(e){var t=this.$el.querySelectorAll("input"),i=this.$el.querySelector('input[value="'+e+'"]');this.poll.multiple?i.checked=!i.checked:((0,o.default)(t,function(e){e.checked=!1}),i.checked=!0),this.choices=(0,a.default)(t,function(e){return e.checked})},optionId:function(e){return"poll"+this.poll.id+"-"+e},vote:function(){var e=this;0!==this.choiceIndices.length&&(this.loading=!0,this.$store.dispatch("votePoll",{id:this.statusId,pollId:this.poll.id,choices:this.choiceIndices}).then(function(t){e.loading=!1}))}}}},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a=function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)Object.prototype.hasOwnProperty.call(e,i)&&(t[i]=e[i]);return t.default=e,t}(i(404));t.default={name:"Timeago",props:["time","autoUpdate","longFormat","nowThreshold"],data:function(){return{relativeTime:{key:"time.now",num:0},interval:null}},created:function(){this.refreshRelativeTimeObject()},destroyed:function(){clearTimeout(this.interval)},computed:{localeDateString:function(){return"string"==typeof this.time?new Date(Date.parse(this.time)).toLocaleString():this.time.toLocaleString()}},methods:{refreshRelativeTimeObject:function(){var e="number"==typeof this.nowThreshold?this.nowThreshold:1;this.relativeTime=this.longFormat?a.relativeTime(this.time,e):a.relativeTimeShort(this.time,e),this.autoUpdate&&(this.interval=setTimeout(this.refreshRelativeTimeObject,1e3*this.autoUpdate))}}}},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a,o=i(405);var n={props:["status"],components:{Popper:((a=o)&&a.__esModule?a:{default:a}).default},data:function(){return{showDropDown:!1,showPopper:!0}},methods:{deleteStatus:function(){this.refreshPopper(),window.confirm(this.$t("status.delete_confirm"))&&this.$store.dispatch("deleteStatus",{id:this.status.id})},toggleMenu:function(){this.showDropDown=!this.showDropDown},pinStatus:function(){var e=this;this.refreshPopper(),this.$store.dispatch("pinStatus",this.status.id).then(function(){return e.$emit("onSuccess")}).catch(function(t){return e.$emit("onError",t.error.error)})},unpinStatus:function(){var e=this;this.refreshPopper(),this.$store.dispatch("unpinStatus",this.status.id).then(function(){return e.$emit("onSuccess")}).catch(function(t){return e.$emit("onError",t.error.error)})},refreshPopper:function(){var e=this;this.showPopper=!1,this.showDropDown=!1,setTimeout(function(){e.showPopper=!0})}},computed:{currentUser:function(){return this.$store.state.users.currentUser},canDelete:function(){if(this.currentUser)return this.currentUser.rights.moderator||this.currentUser.rights.admin||this.status.user.id===this.currentUser.id},ownStatus:function(){return this.status.user.id===this.currentUser.id},canPin:function(){return this.ownStatus&&("public"===this.status.visibility||"unlisted"===this.status.visibility)},enabled:function(){return this.canPin||this.canDelete}}};t.default=n},,function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a=m(i(24)),o=m(i(400)),n=m(i(22)),s=m(i(406)),r=m(i(407)),l=m(i(715)),c=m(i(409)),u=m(i(410)),d=m(i(725)),p=m(i(73)),f=m(i(411));function m(e){return e&&e.__esModule?e:{default:e}}var h={props:["replyTo","repliedUser","attentions","copyMessageScope","subject"],components:{MediaUpload:l.default,EmojiInput:u.default,PollForm:d.default,ScopeSelector:c.default},mounted:function(){this.resize(this.$refs.textarea);var e=this.$refs.textarea.value.length;this.$refs.textarea.setSelectionRange(e,e),this.replyTo&&this.$refs.textarea.focus()},data:function(){var e=this.$route.query.message||"",t=void 0===this.$store.state.config.scopeCopy?this.$store.state.instance.scopeCopy:this.$store.state.config.scopeCopy;if(this.replyTo){var i=this.$store.state.users.currentUser;e=function(e,t){var i=e.user,r=e.attentions,l=[].concat((0,a.default)(r));l.unshift(i),l=(0,o.default)(l,"id"),l=(0,s.default)(l,{id:t.id});var c=(0,n.default)(l,function(e){return"@"+e.screen_name});return c.length>0?c.join(" ")+" ":""}({user:this.repliedUser,attentions:this.attentions},i)}var r=this.copyMessageScope&&t||"direct"===this.copyMessageScope?this.copyMessageScope:this.$store.state.users.currentUser.default_scope,l=void 0===this.$store.state.config.postContentType?this.$store.state.instance.postContentType:this.$store.state.config.postContentType;return{dropFiles:[],submitDisabled:!1,error:null,posting:!1,highlighted:0,newStatus:{spoilerText:this.subject||"",status:e,nsfw:!1,files:[],poll:{},visibility:r,contentType:l},caret:0,pollFormVisible:!1}},computed:{users:function(){return this.$store.state.users.users},userDefaultScope:function(){return this.$store.state.users.currentUser.default_scope},showAllScopes:function(){return!(void 0===this.$store.state.config.minimalScopesMode?this.$store.state.instance.minimalScopesMode:this.$store.state.config.minimalScopesMode)},emojiUserSuggestor:function(){return(0,f.default)({emoji:[].concat((0,a.default)(this.$store.state.instance.emoji),(0,a.default)(this.$store.state.instance.customEmoji)),users:this.$store.state.users.users})},emojiSuggestor:function(){return(0,f.default)({emoji:[].concat((0,a.default)(this.$store.state.instance.emoji),(0,a.default)(this.$store.state.instance.customEmoji))})},emoji:function(){return this.$store.state.instance.emoji||[]},customEmoji:function(){return this.$store.state.instance.customEmoji||[]},statusLength:function(){return this.newStatus.status.length},spoilerTextLength:function(){return this.newStatus.spoilerText.length},statusLengthLimit:function(){return this.$store.state.instance.textlimit},hasStatusLengthLimit:function(){return this.statusLengthLimit>0},charactersLeft:function(){return this.statusLengthLimit-(this.statusLength+this.spoilerTextLength)},isOverLengthLimit:function(){return this.hasStatusLengthLimit&&this.charactersLeft<0},minimalScopesMode:function(){return this.$store.state.instance.minimalScopesMode},alwaysShowSubject:function(){return void 0!==this.$store.state.config.alwaysShowSubjectInput?this.$store.state.config.alwaysShowSubjectInput:void 0===this.$store.state.instance.alwaysShowSubjectInput||this.$store.state.instance.alwaysShowSubjectInput},postFormats:function(){return this.$store.state.instance.postFormats||[]},safeDMEnabled:function(){return this.$store.state.instance.safeDM},pollsAvailable:function(){return this.$store.state.instance.pollsAvailable&&this.$store.state.instance.pollLimits.max_options>=2},hideScopeNotice:function(){return this.$store.state.config.hideScopeNotice},pollContentError:function(){return this.pollFormVisible&&this.newStatus.poll&&this.newStatus.poll.error}},methods:{postStatus:function(e){var t=this;if(!this.posting&&!this.submitDisabled){if(""===this.newStatus.status){if(!(this.newStatus.files.length>0))return void(this.error="Cannot post an empty status with no files");this.newStatus.status=""}var i=this.pollFormVisible?this.newStatus.poll:{};this.pollContentError?this.error=this.pollContentError:(this.posting=!0,r.default.postStatus({status:e.status,spoilerText:e.spoilerText||null,visibility:e.visibility,sensitive:e.nsfw,media:e.files,store:this.$store,inReplyToStatusId:this.replyTo,contentType:e.contentType,poll:i}).then(function(i){if(i.error)t.error=i.error;else{t.newStatus={status:"",spoilerText:"",files:[],visibility:e.visibility,contentType:e.contentType,poll:{}},t.pollFormVisible=!1,t.$refs.mediaUpload.clearFile(),t.clearPollForm(),t.$emit("posted");var a=t.$el.querySelector("textarea");a.style.height="auto",a.style.height=void 0,t.error=null}t.posting=!1}))}},addMediaFile:function(e){this.newStatus.files.push(e),this.enableSubmit()},removeMediaFile:function(e){var t=this.newStatus.files.indexOf(e);this.newStatus.files.splice(t,1)},uploadFailed:function(e,t){t=t||{},this.error=this.$t("upload.error.base")+" "+this.$t("upload.error."+e,t),this.enableSubmit()},disableSubmit:function(){this.submitDisabled=!0},enableSubmit:function(){this.submitDisabled=!1},type:function(e){return p.default.fileType(e.mimetype)},paste:function(e){e.clipboardData.files.length>0&&(e.preventDefault(),this.dropFiles=[e.clipboardData.files[0]])},fileDrop:function(e){e.dataTransfer.files.length>0&&(e.preventDefault(),this.dropFiles=e.dataTransfer.files)},fileDrag:function(e){e.dataTransfer.dropEffect="copy"},resize:function(e){var t=e.target||e;if(t instanceof window.Element){var i=Number(window.getComputedStyle(t)["padding-top"].substr(0,1))+Number(window.getComputedStyle(t)["padding-bottom"].substr(0,1));t.style.height="auto",t.style.height=t.scrollHeight-i+"px",""===t.value&&(t.style.height=null)}},clearError:function(){this.error=null},changeVis:function(e){this.newStatus.visibility=e},togglePollForm:function(){this.pollFormVisible=!this.pollFormVisible},setPoll:function(e){this.newStatus.poll=e},clearPollForm:function(){this.$refs.pollForm&&this.$refs.pollForm.clear()},dismissScopeNotice:function(){this.$store.dispatch("setOption",{name:"hideScopeNotice",value:!0})}}};t.default=h},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a=n(i(407)),o=n(i(408));function n(e){return e&&e.__esModule?e:{default:e}}var s={data:function(){return{uploading:!1,uploadReady:!0}},methods:{uploadFile:function(e){var t=this,i=this.$store;if(e.size>i.state.instance.uploadlimit){var n=o.default.fileSizeFormat(e.size),s=o.default.fileSizeFormat(i.state.instance.uploadlimit);t.$emit("upload-failed","file_too_big",{filesize:n.num,filesizeunit:n.unit,allowedsize:s.num,allowedsizeunit:s.unit})}else{var r=new FormData;r.append("file",e),t.$emit("uploading"),t.uploading=!0,a.default.uploadMedia({store:i,formData:r}).then(function(e){t.$emit("uploaded",e),t.uploading=!1},function(e){t.$emit("upload-failed","default"),t.uploading=!1})}},fileDrop:function(e){e.dataTransfer.files.length>0&&(e.preventDefault(),this.uploadFile(e.dataTransfer.files[0]))},fileDrag:function(e){e.dataTransfer.types.contains("Files")?e.dataTransfer.dropEffect="copy":e.dataTransfer.dropEffect="none"},clearFile:function(){var e=this;this.uploadReady=!1,this.$nextTick(function(){e.uploadReady=!0})},change:function(e){for(var t=e.target,i=0;i0?this.$store.dispatch("setPageTitle","("+e+")"):this.$store.dispatch("setPageTitle","")}},methods:{markAsSeen:function(){this.$store.dispatch("markNotificationsAsSeen")},fetchOlderNotifications:function(){var e=this;if(!this.loading){var t=this.$store,i=t.state.users.currentUser.credentials;t.commit("setNotificationsLoading",{value:!0}),o.default.fetchAndUpdate({store:t,credentials:i,older:!0}).then(function(i){t.commit("setNotificationsLoading",{value:!1}),0===i.length&&(e.bottomedOut=!0)})}}}};t.default=r},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a=c(i(101)),o=c(i(75)),n=c(i(51)),s=c(i(228)),r=i(416),l=c(i(42));function c(e){return e&&e.__esModule?e:{default:e}}var u={data:function(){return{userExpanded:!1,betterShadow:this.$store.state.interface.browserSupport.cssFilter}},props:["notification"],components:{Status:a.default,UserAvatar:o.default,UserCard:n.default,Timeago:s.default},methods:{toggleUserExpanded:function(){this.userExpanded=!this.userExpanded},userProfileLink:function(e){return(0,l.default)(e.id,e.screen_name,this.$store.state.instance.restrictedNicknames)},getUser:function(e){return this.$store.state.users.usersObject[e.from_profile.id]}},computed:{userClass:function(){return(0,r.highlightClass)(this.notification.from_profile)},userStyle:function(){var e=this.$store.state.config.highlight,t=this.notification.from_profile;return(0,r.highlightStyle)(e[t.screen_name])},userInStore:function(){return this.$store.getters.findUser(this.notification.from_profile.id)},user:function(){return this.userInStore?this.userInStore:this.notification.from_profile}}};t.default=u},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a,o=i(50);var n={computed:{timeline:function(){return this.$store.state.statuses.timelines.dms}},components:{Timeline:((a=o)&&a.__esModule?a:{default:a}).default}};t.default=n},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a=d(i(216)),o=d(i(51)),n=d(i(233)),s=d(i(50)),r=d(i(231)),l=d(i(413)),c=d(i(234)),u=d(i(794));function d(e){return e&&e.__esModule?e:{default:e}}var p=(0,u.default)({fetch:function(e,t){return t.dispatch("fetchFollowers",e.userId)},select:function(e,t){return(0,a.default)(t.getters.findUser(e.userId),"followerIds",[]).map(function(e){return t.getters.findUser(e)})},destroy:function(e,t){return t.dispatch("clearFollowers",e.userId)},childPropName:"items",additionalPropNames:["userId"]})(c.default),f=(0,u.default)({fetch:function(e,t){return t.dispatch("fetchFriends",e.userId)},select:function(e,t){return(0,a.default)(t.getters.findUser(e.userId),"friendIds",[]).map(function(e){return t.getters.findUser(e)})},destroy:function(e,t){return t.dispatch("clearFriends",e.userId)},childPropName:"items",additionalPropNames:["userId"]})(c.default),m={data:function(){return{error:!1,userId:null}},created:function(){var e=this.$route.params;this.load(e.name||e.id)},destroyed:function(){this.cleanUp()},computed:{timeline:function(){return this.$store.state.statuses.timelines.user},favorites:function(){return this.$store.state.statuses.timelines.favorites},media:function(){return this.$store.state.statuses.timelines.media},isUs:function(){return this.userId&&this.$store.state.users.currentUser.id&&this.userId===this.$store.state.users.currentUser.id},user:function(){return this.$store.getters.findUser(this.userId)},isExternal:function(){return"external-user-profile"===this.$route.name},followsTabVisible:function(){return this.isUs||!this.user.hide_follows},followersTabVisible:function(){return this.isUs||!this.user.hide_followers}},methods:{load:function(e){var t=this,i=this.$store.getters.findUser(e);i?(this.userId=i.id,this.fetchTimelines()):this.$store.dispatch("fetchUser",e).then(function(e){var i=e.id;t.userId=i,t.fetchTimelines()}).catch(function(e){var i=(0,a.default)(e,"error.error");t.error="No user with such user_id"===i?t.$t("user_profile.profile_does_not_exist"):i||t.$t("user_profile.profile_loading_error")})},fetchTimelines:function(){var e=this.userId;this.$store.dispatch("startFetchingTimeline",{timeline:"user",userId:e}),this.$store.dispatch("startFetchingTimeline",{timeline:"media",userId:e}),this.isUs&&this.$store.dispatch("startFetchingTimeline",{timeline:"favorites",userId:e}),this.$store.dispatch("fetchPinnedStatuses",e)},cleanUp:function(){this.$store.dispatch("stopFetching","user"),this.$store.dispatch("stopFetching","favorites"),this.$store.dispatch("stopFetching","media"),this.$store.commit("clearTimeline",{timeline:"user"}),this.$store.commit("clearTimeline",{timeline:"favorites"}),this.$store.commit("clearTimeline",{timeline:"media"})}},watch:{"$route.params.id":function(e){e&&(this.cleanUp(),this.load(e))},"$route.params.name":function(e){e&&(this.cleanUp(),this.load(e))},$route:function(){this.$refs.tabSwitcher.activateTab(0)()}},components:{UserCard:o.default,Timeline:s.default,FollowerList:p,FriendList:f,ModerationTools:l.default,FollowCard:n.default,Conversation:r.default}};t.default=m},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a=s(i(103)),o=s(i(412)),n=i(414);function s(e){return e&&e.__esModule?e:{default:e}}var r={props:["user","noFollowsYou"],data:function(){return{inProgress:!1,requestSent:!1}},components:{BasicUserCard:a.default,RemoteFollow:o.default},computed:{isMe:function(){return this.$store.state.users.currentUser.id===this.user.id},loggedIn:function(){return this.$store.state.users.currentUser}},methods:{followUser:function(){var e=this;this.inProgress=!0,(0,n.requestFollow)(this.user,this.$store).then(function(t){var i=t.sent;e.inProgress=!1,e.requestSent=i})},unfollowUser:function(){var e=this;this.inProgress=!0,(0,n.requestUnfollow)(this.user,this.$store).then(function(){e.inProgress=!1})}}};t.default=r},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a=s(i(51)),o=s(i(75)),n=s(i(42));function s(e){return e&&e.__esModule?e:{default:e}}var r={props:["user"],data:function(){return{userExpanded:!1}},components:{UserCard:a.default,UserAvatar:o.default},methods:{toggleUserExpanded:function(){this.userExpanded=!this.userExpanded},userProfileLink:function(e){return(0,n.default)(e.id,e.screen_name,this.$store.state.instance.restrictedNicknames)}}};t.default=r},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={props:{items:{type:Array,default:function(){return[]}},getKey:{type:Function,default:function(e){return e.id}}}}},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a=u(i(800)),o=u(i(803)),n=u(i(74)),s=u(i(235)),r=u(i(420)),l=u(i(824)),c=i(825);function u(e){return e&&e.__esModule?e:{default:e}}var d={data:function(){var e=this.$store.state.config,t=this.$store.state.instance;return{hideAttachmentsLocal:e.hideAttachments,hideAttachmentsInConvLocal:e.hideAttachmentsInConv,maxThumbnails:e.maxThumbnails,hideNsfwLocal:e.hideNsfw,useOneClickNsfw:e.useOneClickNsfw,hideISPLocal:e.hideISP,preloadImage:e.preloadImage,hidePostStatsLocal:void 0===e.hidePostStats?t.hidePostStats:e.hidePostStats,hidePostStatsDefault:this.$t("settings.values."+t.hidePostStats),hideUserStatsLocal:void 0===e.hideUserStats?t.hideUserStats:e.hideUserStats,hideUserStatsDefault:this.$t("settings.values."+t.hideUserStats),hideFilteredStatusesLocal:void 0===e.hideFilteredStatuses?t.hideFilteredStatuses:e.hideFilteredStatuses,hideFilteredStatusesDefault:this.$t("settings.values."+t.hideFilteredStatuses),notificationVisibilityLocal:e.notificationVisibility,replyVisibilityLocal:e.replyVisibility,loopVideoLocal:e.loopVideo,muteWordsString:e.muteWords.join("\n"),autoLoadLocal:e.autoLoad,streamingLocal:e.streaming,pauseOnUnfocusedLocal:e.pauseOnUnfocused,hoverPreviewLocal:e.hoverPreview,autohideFloatingPostButtonLocal:e.autohideFloatingPostButton,hideMutedPostsLocal:void 0===e.hideMutedPosts?t.hideMutedPosts:e.hideMutedPosts,hideMutedPostsDefault:this.$t("settings.values."+t.hideMutedPosts),collapseMessageWithSubjectLocal:void 0===e.collapseMessageWithSubject?t.collapseMessageWithSubject:e.collapseMessageWithSubject,collapseMessageWithSubjectDefault:this.$t("settings.values."+t.collapseMessageWithSubject),subjectLineBehaviorLocal:void 0===e.subjectLineBehavior?t.subjectLineBehavior:e.subjectLineBehavior,subjectLineBehaviorDefault:t.subjectLineBehavior,postContentTypeLocal:void 0===e.postContentType?t.postContentType:e.postContentType,postContentTypeDefault:t.postContentType,alwaysShowSubjectInputLocal:void 0===e.alwaysShowSubjectInput?t.alwaysShowSubjectInput:e.alwaysShowSubjectInput,alwaysShowSubjectInputDefault:this.$t("settings.values."+t.alwaysShowSubjectInput),scopeCopyLocal:void 0===e.scopeCopy?t.scopeCopy:e.scopeCopy,scopeCopyDefault:this.$t("settings.values."+t.scopeCopy),minimalScopesModeLocal:void 0===e.minimalScopesMode?t.minimalScopesMode:e.minimalScopesMode,minimalScopesModeDefault:this.$t("settings.values."+t.minimalScopesMode),stopGifs:e.stopGifs,webPushNotificationsLocal:e.webPushNotifications,loopVideoSilentOnlyLocal:e.loopVideosSilentOnly,loopSilentAvailable:(0,a.default)(HTMLVideoElement.prototype,"mozHasAudio")||(0,a.default)(HTMLMediaElement.prototype,"webkitAudioDecodedByteCount")||(0,a.default)(HTMLMediaElement.prototype,"audioTracks"),playVideosInModal:e.playVideosInModal,useContainFit:e.useContainFit,backendVersion:t.backendVersion,frontendVersion:t.frontendVersion}},components:{TabSwitcher:s.default,StyleSwitcher:r.default,InterfaceLanguageSwitcher:l.default},computed:{user:function(){return this.$store.state.users.currentUser},currentSaveStateNotice:function(){return this.$store.state.interface.settings.currentSaveStateNotice},postFormats:function(){return this.$store.state.instance.postFormats||[]},instanceSpecificPanelPresent:function(){return this.$store.state.instance.showInstanceSpecificPanel},frontendVersionLink:function(){return"https://git.pleroma.social/pleroma/pleroma-fe/commit/"+this.frontendVersion},backendVersionLink:function(){return"https://git.pleroma.social/pleroma/pleroma/commit/"+(0,c.extractCommit)(this.backendVersion)}},watch:{hideAttachmentsLocal:function(e){this.$store.dispatch("setOption",{name:"hideAttachments",value:e})},hideAttachmentsInConvLocal:function(e){this.$store.dispatch("setOption",{name:"hideAttachmentsInConv",value:e})},hidePostStatsLocal:function(e){this.$store.dispatch("setOption",{name:"hidePostStats",value:e})},hideUserStatsLocal:function(e){this.$store.dispatch("setOption",{name:"hideUserStats",value:e})},hideFilteredStatusesLocal:function(e){this.$store.dispatch("setOption",{name:"hideFilteredStatuses",value:e})},hideNsfwLocal:function(e){this.$store.dispatch("setOption",{name:"hideNsfw",value:e})},useOneClickNsfw:function(e){this.$store.dispatch("setOption",{name:"useOneClickNsfw",value:e})},preloadImage:function(e){this.$store.dispatch("setOption",{name:"preloadImage",value:e})},hideISPLocal:function(e){this.$store.dispatch("setOption",{name:"hideISP",value:e})},"notificationVisibilityLocal.likes":function(e){this.$store.dispatch("setOption",{name:"notificationVisibility",value:this.$store.state.config.notificationVisibility})},"notificationVisibilityLocal.follows":function(e){this.$store.dispatch("setOption",{name:"notificationVisibility",value:this.$store.state.config.notificationVisibility})},"notificationVisibilityLocal.repeats":function(e){this.$store.dispatch("setOption",{name:"notificationVisibility",value:this.$store.state.config.notificationVisibility})},"notificationVisibilityLocal.mentions":function(e){this.$store.dispatch("setOption",{name:"notificationVisibility",value:this.$store.state.config.notificationVisibility})},replyVisibilityLocal:function(e){this.$store.dispatch("setOption",{name:"replyVisibility",value:e})},loopVideoLocal:function(e){this.$store.dispatch("setOption",{name:"loopVideo",value:e})},loopVideoSilentOnlyLocal:function(e){this.$store.dispatch("setOption",{name:"loopVideoSilentOnly",value:e})},autoLoadLocal:function(e){this.$store.dispatch("setOption",{name:"autoLoad",value:e})},streamingLocal:function(e){this.$store.dispatch("setOption",{name:"streaming",value:e})},pauseOnUnfocusedLocal:function(e){this.$store.dispatch("setOption",{name:"pauseOnUnfocused",value:e})},hoverPreviewLocal:function(e){this.$store.dispatch("setOption",{name:"hoverPreview",value:e})},autohideFloatingPostButtonLocal:function(e){this.$store.dispatch("setOption",{name:"autohideFloatingPostButton",value:e})},muteWordsString:function(e){e=(0,n.default)(e.split("\n"),function(e){return(0,o.default)(e).length>0}),this.$store.dispatch("setOption",{name:"muteWords",value:e})},hideMutedPostsLocal:function(e){this.$store.dispatch("setOption",{name:"hideMutedPosts",value:e})},collapseMessageWithSubjectLocal:function(e){this.$store.dispatch("setOption",{name:"collapseMessageWithSubject",value:e})},scopeCopyLocal:function(e){this.$store.dispatch("setOption",{name:"scopeCopy",value:e})},alwaysShowSubjectInputLocal:function(e){this.$store.dispatch("setOption",{name:"alwaysShowSubjectInput",value:e})},subjectLineBehaviorLocal:function(e){this.$store.dispatch("setOption",{name:"subjectLineBehavior",value:e})},postContentTypeLocal:function(e){this.$store.dispatch("setOption",{name:"postContentType",value:e})},minimalScopesModeLocal:function(e){this.$store.dispatch("setOption",{name:"minimalScopesMode",value:e})},stopGifs:function(e){this.$store.dispatch("setOption",{name:"stopGifs",value:e})},webPushNotificationsLocal:function(e){this.$store.dispatch("setOption",{name:"webPushNotifications",value:e}),e&&this.$store.dispatch("registerPushNotifications")},playVideosInModal:function(e){this.$store.dispatch("setOption",{name:"playVideosInModal",value:e})},useContainFit:function(e){this.$store.dispatch("setOption",{name:"useContainFit",value:e})},maxThumbnails:function(e){e=this.maxThumbnails=Math.floor(Math.max(e,0)),this.$store.dispatch("setOption",{name:"maxThumbnails",value:e})}}};t.default=d},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a=x(i(93)),o=x(i(218)),n=x(i(36)),s=x(i(28)),r=x(i(364)),l=x(i(24)),c=x(i(14)),u=x(i(35)),d=i(63),p=i(10),f=i(80),m=x(i(421)),h=x(i(811)),_=x(i(422)),v=x(i(812)),g=x(i(815)),b=x(i(818)),w=x(i(235)),y=x(i(956)),k=x(i(821));function x(e){return e&&e.__esModule?e:{default:e}}var C=["bg","fg","text","link","cRed","cGreen","cBlue","cOrange"].map(function(e){return e+"ColorLocal"});t.default={data:function(){return{availableStyles:[],selected:this.$store.state.config.theme,previewShadows:{},previewColors:{},previewRadii:{},previewFonts:{},shadowsInvalid:!0,colorsInvalid:!0,radiiInvalid:!0,keepColor:!1,keepShadows:!1,keepOpacity:!1,keepRoundness:!1,keepFonts:!1,textColorLocal:"",linkColorLocal:"",bgColorLocal:"",bgOpacityLocal:void 0,fgColorLocal:"",fgTextColorLocal:void 0,fgLinkColorLocal:void 0,btnColorLocal:void 0,btnTextColorLocal:void 0,btnOpacityLocal:void 0,inputColorLocal:void 0,inputTextColorLocal:void 0,inputOpacityLocal:void 0,panelColorLocal:void 0,panelTextColorLocal:void 0,panelLinkColorLocal:void 0,panelFaintColorLocal:void 0,panelOpacityLocal:void 0,topBarColorLocal:void 0,topBarTextColorLocal:void 0,topBarLinkColorLocal:void 0,alertErrorColorLocal:void 0,badgeOpacityLocal:void 0,badgeNotificationColorLocal:void 0,borderColorLocal:void 0,borderOpacityLocal:void 0,faintColorLocal:void 0,faintOpacityLocal:void 0,faintLinkColorLocal:void 0,cRedColorLocal:"",cBlueColorLocal:"",cGreenColorLocal:"",cOrangeColorLocal:"",shadowSelected:void 0,shadowsLocal:{},fontsLocal:{},btnRadiusLocal:"",inputRadiusLocal:"",checkboxRadiusLocal:"",panelRadiusLocal:"",avatarRadiusLocal:"",avatarAltRadiusLocal:"",attachmentRadiusLocal:"",tooltipRadiusLocal:""}},created:function(){var e=this;(0,f.getThemes)().then(function(t){e.availableStyles=t})},mounted:function(){this.normalizeLocalState(this.$store.state.config.customTheme),void 0===this.shadowSelected&&(this.shadowSelected=this.shadowsAvailable[0])},computed:{selectedVersion:function(){return Array.isArray(this.selected)?1:2},currentColors:function(){return{bg:this.bgColorLocal,text:this.textColorLocal,link:this.linkColorLocal,fg:this.fgColorLocal,fgText:this.fgTextColorLocal,fgLink:this.fgLinkColorLocal,panel:this.panelColorLocal,panelText:this.panelTextColorLocal,panelLink:this.panelLinkColorLocal,panelFaint:this.panelFaintColorLocal,input:this.inputColorLocal,inputText:this.inputTextColorLocal,topBar:this.topBarColorLocal,topBarText:this.topBarTextColorLocal,topBarLink:this.topBarLinkColorLocal,btn:this.btnColorLocal,btnText:this.btnTextColorLocal,alertError:this.alertErrorColorLocal,badgeNotification:this.badgeNotificationColorLocal,faint:this.faintColorLocal,faintLink:this.faintLinkColorLocal,border:this.borderColorLocal,cRed:this.cRedColorLocal,cBlue:this.cBlueColorLocal,cGreen:this.cGreenColorLocal,cOrange:this.cOrangeColorLocal}},currentOpacity:function(){return{bg:this.bgOpacityLocal,btn:this.btnOpacityLocal,input:this.inputOpacityLocal,panel:this.panelOpacityLocal,topBar:this.topBarOpacityLocal,border:this.borderOpacityLocal,faint:this.faintOpacityLocal}},currentRadii:function(){return{btn:this.btnRadiusLocal,input:this.inputRadiusLocal,checkbox:this.checkboxRadiusLocal,panel:this.panelRadiusLocal,avatar:this.avatarRadiusLocal,avatarAlt:this.avatarAltRadiusLocal,tooltip:this.tooltipRadiusLocal,attachment:this.attachmentRadiusLocal}},preview:function(){return(0,f.composePreset)(this.previewColors,this.previewRadii,this.previewShadows,this.previewFonts)},previewTheme:function(){return this.preview.theme.colors?this.preview.theme:{colors:{},opacity:{},radii:{},shadows:{},fonts:{}}},previewContrast:function(){if(!this.previewTheme.colors.bg)return{};var e=this.previewTheme.colors,t=this.previewTheme.opacity;if(!e.bg)return{};var i={text:(0,d.hex2rgb)(e.text),panelText:(0,d.hex2rgb)(e.panelText),panelLink:(0,d.hex2rgb)(e.panelLink),btnText:(0,d.hex2rgb)(e.btnText),topBarText:(0,d.hex2rgb)(e.topBarText),inputText:(0,d.hex2rgb)(e.inputText),link:(0,d.hex2rgb)(e.link),topBarLink:(0,d.hex2rgb)(e.topBarLink),red:(0,d.hex2rgb)(e.cRed),green:(0,d.hex2rgb)(e.cGreen),blue:(0,d.hex2rgb)(e.cBlue),orange:(0,d.hex2rgb)(e.cOrange)},a={bg:(0,d.hex2rgb)(e.bg),btn:(0,d.hex2rgb)(e.btn),panel:(0,d.hex2rgb)(e.panel),topBar:(0,d.hex2rgb)(e.topBar),input:(0,d.hex2rgb)(e.input),alertError:(0,d.hex2rgb)(e.alertError),badgeNotification:(0,d.hex2rgb)(e.badgeNotification)},o={bgText:(0,d.getContrastRatio)((0,d.alphaBlend)(a.bg,t.bg,i.text),i.text),bgLink:(0,d.getContrastRatio)((0,d.alphaBlend)(a.bg,t.bg,i.link),i.link),bgRed:(0,d.getContrastRatio)((0,d.alphaBlend)(a.bg,t.bg,i.red),i.red),bgGreen:(0,d.getContrastRatio)((0,d.alphaBlend)(a.bg,t.bg,i.green),i.green),bgBlue:(0,d.getContrastRatio)((0,d.alphaBlend)(a.bg,t.bg,i.blue),i.blue),bgOrange:(0,d.getContrastRatio)((0,d.alphaBlend)(a.bg,t.bg,i.orange),i.orange),tintText:(0,d.getContrastRatio)((0,d.alphaBlend)(a.bg,.5,i.panelText),i.text),panelText:(0,d.getContrastRatio)((0,d.alphaBlend)(a.panel,t.panel,i.panelText),i.panelText),panelLink:(0,d.getContrastRatio)((0,d.alphaBlend)(a.panel,t.panel,i.panelLink),i.panelLink),btnText:(0,d.getContrastRatio)((0,d.alphaBlend)(a.btn,t.btn,i.btnText),i.btnText),inputText:(0,d.getContrastRatio)((0,d.alphaBlend)(a.input,t.input,i.inputText),i.inputText),topBarText:(0,d.getContrastRatio)((0,d.alphaBlend)(a.topBar,t.topBar,i.topBarText),i.topBarText),topBarLink:(0,d.getContrastRatio)((0,d.alphaBlend)(a.topBar,t.topBar,i.topBarLink),i.topBarLink)};return(0,u.default)(o).reduce(function(e,t){var i,a=(0,c.default)(t,2),o=a[0],n=a[1];return e[o]={text:(i=n).toPrecision(3)+":1",aa:i>=4.5,aaa:i>=7,laa:i>=3,laaa:i>=4.5},e},{})},previewRules:function(){return this.preview.rules?[].concat((0,l.default)((0,r.default)(this.preview.rules)),["color: var(--text)","font-family: var(--interfaceFont, sans-serif)"]).join(";"):""},shadowsAvailable:function(){return(0,s.default)(this.previewTheme.shadows).sort()},currentShadowOverriden:{get:function(){return!!this.currentShadow},set:function(e){e?(0,p.set)(this.shadowsLocal,this.shadowSelected,this.currentShadowFallback.map(function(e){return(0,n.default)({},e)})):(0,p.delete)(this.shadowsLocal,this.shadowSelected)}},currentShadowFallback:function(){return this.previewTheme.shadows[this.shadowSelected]},currentShadow:{get:function(){return this.shadowsLocal[this.shadowSelected]},set:function(e){(0,p.set)(this.shadowsLocal,this.shadowSelected,e)}},themeValid:function(){return!this.shadowsInvalid&&!this.colorsInvalid&&!this.radiiInvalid},exportedTheme:function(){var e=!(this.keepFonts||this.keepShadows||this.keepOpacity||this.keepRoundness||this.keepColor),t={};return(this.keepFonts||e)&&(t.fonts=this.fontsLocal),(this.keepShadows||e)&&(t.shadows=this.shadowsLocal),(this.keepOpacity||e)&&(t.opacity=this.currentOpacity),(this.keepColor||e)&&(t.colors=this.currentColors),(this.keepRoundness||e)&&(t.radii=this.currentRadii),{_pleroma_theme_version:2,theme:t}}},components:{ColorInput:m.default,OpacityInput:_.default,RangeInput:h.default,ContrastRatio:b.default,ShadowControl:v.default,FontControl:g.default,TabSwitcher:w.default,Preview:y.default,ExportImport:k.default},methods:{setCustomTheme:function(){this.$store.dispatch("setOption",{name:"customTheme",value:{shadows:this.shadowsLocal,fonts:this.fontsLocal,opacity:this.currentOpacity,colors:this.currentColors,radii:this.currentRadii}})},onImport:function(e){1===e._pleroma_theme_version?this.normalizeLocalState(e,1):2===e._pleroma_theme_version&&this.normalizeLocalState(e.theme,2)},importValidator:function(e){var t=e._pleroma_theme_version;return t>=1||t<=2},clearAll:function(){var e=this.$store.state.config.customTheme.colors?2:"l1";this.normalizeLocalState(this.$store.state.config.customTheme,e)},clearV1:function(){var e=this;(0,s.default)(this.$data).filter(function(e){return e.endsWith("ColorLocal")||e.endsWith("OpacityLocal")}).filter(function(e){return!C.includes(e)}).forEach(function(t){(0,p.set)(e.$data,t,void 0)})},clearRoundness:function(){var e=this;(0,s.default)(this.$data).filter(function(e){return e.endsWith("RadiusLocal")}).forEach(function(t){(0,p.set)(e.$data,t,void 0)})},clearOpacity:function(){var e=this;(0,s.default)(this.$data).filter(function(e){return e.endsWith("OpacityLocal")}).forEach(function(t){(0,p.set)(e.$data,t,void 0)})},clearShadows:function(){this.shadowsLocal={}},clearFonts:function(){this.fontsLocal={}},normalizeLocalState:function(e){var t=this,i=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,n=e.colors||e,r=e.radii||e,l=e.opacity,p=e.shadows||{},f=e.fonts||{};if(0===i&&(e.version&&(i=e.version),void 0===n.text&&void 0!==n.fg&&(i=1),void 0!==n.text&&void 0!==n.fg&&(i=2)),1===i&&(this.fgColorLocal=(0,d.rgb2hex)(n.btn),this.textColorLocal=(0,d.rgb2hex)(n.fg)),!this.keepColor){this.clearV1();var m=new o.default(1!==i?(0,s.default)(n):[]);1!==i&&"l1"!==i||m.add("bg").add("link").add("cRed").add("cBlue").add("cGreen").add("cOrange"),m.forEach(function(e){t[e+"ColorLocal"]=(0,d.rgb2hex)(n[e])})}this.keepRoundness||(this.clearRoundness(),(0,u.default)(r).forEach(function(e){var i=(0,c.default)(e,2),a=i[0],o=i[1],n=a.endsWith("Radius")?a.split("Radius")[0]:a;t[n+"RadiusLocal"]=o})),this.keepShadows||(this.clearShadows(),this.shadowsLocal=p,this.shadowSelected=this.shadowsAvailable[0]),this.keepFonts||(this.clearFonts(),this.fontsLocal=f),l&&!this.keepOpacity&&(this.clearOpacity(),(0,u.default)(l).forEach(function(e){var i=(0,c.default)(e,2),o=i[0],n=i[1];null==n||(0,a.default)(n)||(t[o+"OpacityLocal"]=n)}))}},watch:{currentRadii:function(){try{this.previewRadii=(0,f.generateRadii)({radii:this.currentRadii}),this.radiiInvalid=!1}catch(e){this.radiiInvalid=!0,console.warn(e)}},shadowsLocal:{handler:function(){try{this.previewShadows=(0,f.generateShadows)({shadows:this.shadowsLocal}),this.shadowsInvalid=!1}catch(e){this.shadowsInvalid=!0,console.warn(e)}},deep:!0},fontsLocal:{handler:function(){try{this.previewFonts=(0,f.generateFonts)({fonts:this.fontsLocal}),this.fontsInvalid=!1}catch(e){this.fontsInvalid=!0,console.warn(e)}},deep:!0},currentColors:function(){try{this.previewColors=(0,f.generateColors)({opacity:this.currentOpacity,colors:this.currentColors}),this.colorsInvalid=!1}catch(e){this.colorsInvalid=!0,console.warn(e)}},currentOpacity:function(){try{this.previewColors=(0,f.generateColors)({opacity:this.currentOpacity,colors:this.currentColors})}catch(e){console.warn(e)}},selected:function(){1===this.selectedVersion?(this.keepRoundness||this.clearRoundness(),this.keepShadows||this.clearShadows(),this.keepOpacity||this.clearOpacity(),this.keepColor||(this.clearV1(),this.bgColorLocal=this.selected[1],this.fgColorLocal=this.selected[2],this.textColorLocal=this.selected[3],this.linkColorLocal=this.selected[4],this.cRedColorLocal=this.selected[5],this.cGreenColorLocal=this.selected[6],this.cBlueColorLocal=this.selected[7],this.cOrangeColorLocal=this.selected[8])):this.selectedVersion>=2&&this.normalizeLocalState(this.selected.theme,2)}}}},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={props:["name","label","value","fallback","disabled"],computed:{present:function(){return void 0!==this.value}}}},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={props:["name","value","fallback","disabled","label","max","min","step","hardMin","hardMax"],computed:{present:function(){return void 0!==this.value}}}},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default={props:["name","value","fallback","disabled"],computed:{present:function(){return void 0!==this.value}}}},function(e,t,i){"use strict";Object.defineProperty(t,"__esModule",{value:!0});var a=l(i(36)),o=l(i(421)),n=l(i(422)),s=i(80),r=i(63);function l(e){return e&&e.__esModule?e:{default:e}}t.default={props:["value","fallback","ready"],data:function(){return{selectedId:0,cValue:this.value||this.fallback||[]}},components:{ColorInput:o.default,OpacityInput:n.default},methods:{add:function(){this.cValue.push((0,a.default)({},this.selected)),this.selectedId=this.cValue.length-1},del:function(){this.cValue.splice(this.selectedId,1),this.selectedId=0===this.cValue.length?void 0:this.selectedId-1},moveUp:function(){var e=this.cValue.splice(this.selectedId,1)[0];this.cValue.splice(this.selectedId-1,0,e),this.selectedId-=1},moveDn:function(){var e=this.cValue.splice(this.selectedId,1)[0];this.cValue.splice(this.selectedId+1,0,e),this.selectedId+=1}},beforeUpdate:function(){this.cValue=this.value||this.fallback},computed:{selected:function(){return this.ready&&this.cValue.length>0?this.cValue[this.selectedId]:{x:0,y:0,blur:0,spread:0,inset:!1,color:"#000000",alpha:1}},moveUpValid:function(){return this.ready&&this.selectedId>0},moveDnValid:function(){return this.ready&&this.selectedId
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(/
' + this.status.statusnet_html\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 ownStatus () {\n return this.status.user.id === this.$store.state.users.currentUser.id\n },\n tags () {\n return this.status.tags.filter(tagObj => tagObj.hasOwnProperty('name')).map(tagObj => tagObj.name).join(' ')\n }\n },\n components: {\n Attachment,\n FavoriteButton,\n RetweetButton,\n ExtraButtons,\n PostStatusForm,\n Poll,\n UserCard,\n UserAvatar,\n Gallery,\n LinkPreview,\n AvatarList,\n Timeago\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 linkClicked (event) {\n let { target } = event\n if (target.tagName === 'SPAN') {\n target = target.parentNode\n }\n if (target.tagName === 'A') {\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.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 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 toggleShowMore () {\n if (this.showingTall) {\n this.showingTall = false\n } else if (this.expandingSubject && this.status.summary) {\n this.expandingSubject = false\n } else if (this.hideTallStatus) {\n this.showingTall = true\n } else if (this.hideSubjectStatus && this.status.summary) {\n this.expandingSubject = true\n }\n },\n replyEnter (id, event) {\n this.showPreview = true\n const targetId = id\n const statuses = this.$store.state.statuses.allStatuses\n\n if (!this.preview) {\n // if we have the status somewhere already\n this.preview = find(statuses, { 'id': targetId })\n // or if we have to fetch it\n if (!this.preview) {\n this.$store.state.api.backendInteractor.fetchStatus({ id }).then((status) => {\n this.preview = status\n })\n }\n } else if (this.preview.id !== targetId) {\n this.preview = find(statuses, { 'id': targetId })\n }\n },\n replyLeave () {\n this.showPreview = false\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 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 },\n filters: {\n capitalize: function (str) {\n return str.charAt(0).toUpperCase() + str.slice(1)\n }\n }\n}\n\nexport default Status\n","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'\n\nconst Attachment = {\n props: [\n 'attachment',\n 'nsfw',\n 'statusId',\n 'size',\n 'allowPlay',\n 'setMedia'\n ],\n data () {\n return {\n nsfwImage: this.$store.state.instance.nsfwCensorImage || nsfwImage,\n hideNsfwLocal: this.$store.state.config.hideNsfw,\n preloadImage: this.$store.state.config.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 },\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.$store.state.config.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 (this.$store.state.config.useOneClickNsfw && !this.showHidden) {\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 }\n}\n\nexport default Attachment\n","const StillImage = {\n props: [\n 'src',\n 'referrerpolicy',\n 'mimetype',\n 'imageLoadError'\n ],\n data () {\n return {\n stopGifs: this.$store.state.config.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 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","\nconst VideoAttachment = {\n props: ['attachment', 'controls'],\n data () {\n return {\n loopVideo: this.$store.state.config.loopVideo\n }\n },\n methods: {\n onVideoDataLoad (e) {\n const target = e.srcElement || e.target\n if (typeof target.webkitAudioDecodedByteCount !== 'undefined') {\n // non-zero if video has audio track\n if (target.webkitAudioDecodedByteCount > 0) {\n this.loopVideo = this.loopVideo && !this.$store.state.config.loopVideoSilentOnly\n }\n } else if (typeof target.mozHasAudio !== 'undefined') {\n // true if video has audio track\n if (target.mozHasAudio) {\n this.loopVideo = this.loopVideo && !this.$store.state.config.loopVideoSilentOnly\n }\n } else if (typeof target.audioTracks !== 'undefined') {\n if (target.audioTracks.length > 0) {\n this.loopVideo = this.loopVideo && !this.$store.state.config.loopVideoSilentOnly\n }\n }\n }\n }\n}\n\nexport default VideoAttachment\n","const FavoriteButton = {\n props: ['status', 'loggedIn'],\n data () {\n return {\n hidePostStatsLocal: typeof this.$store.state.config.hidePostStats === 'undefined'\n ? this.$store.state.instance.hidePostStats\n : this.$store.state.config.hidePostStats,\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 }\n}\n\nexport default FavoriteButton\n","const RetweetButton = {\n props: ['status', 'loggedIn', 'visibility'],\n data () {\n return {\n hidePostStatsLocal: typeof this.$store.state.config.hidePostStats === 'undefined'\n ? this.$store.state.instance.hidePostStats\n : this.$store.state.config.hidePostStats,\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 }\n}\n\nexport default RetweetButton\n","import Timeago from '../timeago/timeago.vue'\nimport { forEach, map } from 'lodash'\n\nexport default {\n name: 'Poll',\n props: ['poll', 'statusId'],\n components: { Timeago },\n data () {\n return {\n loading: false,\n choices: [],\n refreshInterval: null\n }\n },\n created () {\n this.refreshInterval = setTimeout(this.refreshPoll, 30 * 1000)\n // Initialize choices to booleans and set its length to match options\n this.choices = this.poll.options.map(_ => false)\n },\n destroyed () {\n clearTimeout(this.refreshInterval)\n },\n computed: {\n expired () {\n return Date.now() > Date.parse(this.poll.expires_at)\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 expiresAt () {\n return Date.parse(this.poll.expires_at).toLocaleString()\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 refreshPoll () {\n if (this.expired) return\n this.fetchPoll()\n this.refreshInterval = setTimeout(this.refreshPoll, 30 * 1000)\n },\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 \n\n\n","import Popper from 'vue-popperjs/src/component/popper.js.vue'\n\nconst ExtraButtons = {\n props: [ 'status' ],\n components: {\n Popper\n },\n data () {\n return {\n showDropDown: false,\n showPopper: true\n }\n },\n methods: {\n deleteStatus () {\n this.refreshPopper()\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 toggleMenu () {\n this.showDropDown = !this.showDropDown\n },\n pinStatus () {\n this.refreshPopper()\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.refreshPopper()\n this.$store.dispatch('unpinStatus', this.status.id)\n .then(() => this.$emit('onSuccess'))\n .catch(err => this.$emit('onError', err.error.error))\n },\n refreshPopper () {\n this.showPopper = false\n this.showDropDown = false\n setTimeout(() => {\n this.showPopper = true\n })\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 enabled () {\n return this.canPin || this.canDelete\n }\n }\n}\n\nexport default ExtraButtons\n","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 { reject, map, uniqBy } from 'lodash'\nimport suggestor from '../emoji-input/suggestor.js'\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 },\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 = typeof this.$store.state.config.scopeCopy === 'undefined'\n ? this.$store.state.instance.scopeCopy\n : this.$store.state.config.scopeCopy\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 contentType = typeof this.$store.state.config.postContentType === 'undefined'\n ? this.$store.state.instance.postContentType\n : this.$store.state.config.postContentType\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 const minimalScopesMode = typeof this.$store.state.config.minimalScopesMode === 'undefined'\n ? this.$store.state.instance.minimalScopesMode\n : this.$store.state.config.minimalScopesMode\n return !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 })\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 if (typeof this.$store.state.config.alwaysShowSubjectInput !== 'undefined') {\n return this.$store.state.config.alwaysShowSubjectInput\n } else if (typeof this.$store.state.instance.alwaysShowSubjectInput !== 'undefined') {\n return this.$store.state.instance.alwaysShowSubjectInput\n } else {\n return true\n }\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.state.config.hideScopeNotice\n },\n pollContentError () {\n return this.pollFormVisible &&\n this.newStatus.poll &&\n this.newStatus.poll.error\n }\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.newStatus.status = '\\u200b' // hack\n } else {\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 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 resize (e) {\n const target = e.target || e\n if (!(target instanceof window.Element)) { return }\n const vertPadding = Number(window.getComputedStyle(target)['padding-top'].substr(0, 1)) +\n Number(window.getComputedStyle(target)['padding-bottom'].substr(0, 1))\n // Auto is needed to make textbox shrink when removing lines\n target.style.height = 'auto'\n target.style.height = `${target.scrollHeight - vertPadding}px`\n if (target.value === '') {\n target.style.height = null\n }\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","/* 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","const ScopeSelector = {\n props: [\n 'showAll',\n 'userDefault',\n 'originalScope',\n 'initialScope',\n 'onScopeChange'\n ],\n data () {\n return {\n currentScope: this.initialScope\n }\n },\n computed: {\n showNothing () {\n return !this.showPublic && !this.showUnlisted && !this.showPrivate && !this.showDirect\n },\n showPublic () {\n return this.originalScope !== 'direct' && this.shouldShow('public')\n },\n showUnlisted () {\n return this.originalScope !== 'direct' && this.shouldShow('unlisted')\n },\n showPrivate () {\n return this.originalScope !== 'direct' && this.shouldShow('private')\n },\n showDirect () {\n return this.shouldShow('direct')\n },\n css () {\n return {\n public: {selected: this.currentScope === 'public'},\n unlisted: {selected: this.currentScope === 'unlisted'},\n private: {selected: this.currentScope === 'private'},\n direct: {selected: this.currentScope === 'direct'}\n }\n }\n },\n methods: {\n shouldShow (scope) {\n return this.showAll ||\n this.currentScope === scope ||\n this.originalScope === scope ||\n this.userDefault === scope ||\n scope === 'direct'\n },\n changeVis (scope) {\n this.currentScope = scope\n this.onScopeChange && this.onScopeChange(scope)\n }\n }\n}\n\nexport default ScopeSelector\n","import Completion from '../../services/completion/completion.js'\nimport { take } from 'lodash'\n\n/**\n * EmojiInput - augmented inputs for emoji and autocomplete support in inputs\n * without having to give up the comfort of and elements\n *\n * Intended usage is:\n *