aboutsummaryrefslogtreecommitdiff
path: root/src/components/status/status.js
diff options
context:
space:
mode:
authorlain <lain@soykaf.club>2020-06-24 17:50:05 +0200
committerlain <lain@soykaf.club>2020-06-24 17:50:05 +0200
commit143da55c56a932e4e88b4959511c59f1d73d37b9 (patch)
tree598cce65273b759d7b064fceaaab20b172d541d3 /src/components/status/status.js
parent7dfa734665bbb74058e221af0f71a88b4f37936d (diff)
parentbbb91d8ae3f1c3d5374de7610e723e63121e8222 (diff)
Merge branch 'develop' of git.pleroma.social:pleroma/pleroma-fe into remove-twitterapi-config
Diffstat (limited to 'src/components/status/status.js')
-rw-r--r--src/components/status/status.js251
1 files changed, 52 insertions, 199 deletions
diff --git a/src/components/status/status.js b/src/components/status/status.js
index fc5956ec..73382521 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -1,24 +1,19 @@
-import Attachment from '../attachment/attachment.vue'
import FavoriteButton from '../favorite_button/favorite_button.vue'
import ReactButton from '../react_button/react_button.vue'
import RetweetButton from '../retweet_button/retweet_button.vue'
-import Poll from '../poll/poll.vue'
import ExtraButtons from '../extra_buttons/extra_buttons.vue'
import PostStatusForm from '../post_status_form/post_status_form.vue'
import UserCard from '../user_card/user_card.vue'
import UserAvatar from '../user_avatar/user_avatar.vue'
-import Gallery from '../gallery/gallery.vue'
-import LinkPreview from '../link-preview/link-preview.vue'
import AvatarList from '../avatar_list/avatar_list.vue'
import Timeago from '../timeago/timeago.vue'
+import StatusContent from '../status_content/status_content.vue'
import StatusPopover from '../status_popover/status_popover.vue'
import EmojiReactions from '../emoji_reactions/emoji_reactions.vue'
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
-import fileType from 'src/services/file_type/file_type.service'
-import { processHtml } from 'src/services/tiny_post_html_processor/tiny_post_html_processor.service.js'
import { highlightClass, highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
-import { mentionMatchesUrl, extractTagFromUrl } from 'src/services/matcher/matcher.service.js'
-import { filter, unescape, uniqBy } from 'lodash'
+import { muteWordHits } from '../../services/status_parser/status_parser.js'
+import { unescape, uniqBy } from 'lodash'
import { mapGetters, mapState } from 'vuex'
const Status = {
@@ -43,20 +38,19 @@ const Status = {
replying: false,
unmuted: false,
userExpanded: false,
- showingTall: this.inConversation && this.focused,
- showingLongSubject: false,
- error: null,
- // not as computed because it sets the initial state which will be changed later
- expandingSubject: !this.$store.getters.mergedConfig.collapseMessageWithSubject
+ error: null
}
},
computed: {
- localCollapseSubjectDefault () {
- return this.mergedConfig.collapseMessageWithSubject
- },
muteWords () {
return this.mergedConfig.muteWords
},
+ showReasonMutedThread () {
+ return (
+ this.status.thread_muted ||
+ (this.status.reblog && this.status.reblog.thread_muted)
+ ) && !this.inConversation
+ },
repeaterClass () {
const user = this.statusoid.user
return highlightClass(user)
@@ -79,10 +73,6 @@ const Status = {
const highlight = this.mergedConfig.highlight
return highlightStyle(highlight[user.screen_name])
},
- hideAttachments () {
- return (this.mergedConfig.hideAttachments && !this.inConversation) ||
- (this.mergedConfig.hideAttachmentsInConv && this.inConversation)
- },
userProfileLink () {
return this.generateUserProfileLink(this.status.user.id, this.status.user.screen_name)
},
@@ -110,15 +100,43 @@ const Status = {
return !!this.currentUser
},
muteWordHits () {
- const statusText = this.status.text.toLowerCase()
- const statusSummary = this.status.summary.toLowerCase()
- const hits = filter(this.muteWords, (muteWord) => {
- return statusText.includes(muteWord.toLowerCase()) || statusSummary.includes(muteWord.toLowerCase())
- })
+ return muteWordHits(this.status, this.muteWords)
+ },
+ muted () {
+ const { status } = this
+ const { reblog } = status
+ const relationship = this.$store.getters.relationship(status.user.id)
+ const relationshipReblog = reblog && this.$store.getters.relationship(reblog.user.id)
+ const reasonsToMute = (
+ // Post is muted according to BE
+ status.muted ||
+ // Reprööt of a muted post according to BE
+ (reblog && reblog.muted) ||
+ // Muted user
+ relationship.muting ||
+ // Muted user of a reprööt
+ (relationshipReblog && relationshipReblog.muting) ||
+ // Thread is muted
+ status.thread_muted ||
+ // Wordfiltered
+ this.muteWordHits.length > 0
+ )
+ const excusesNotToMute = (
+ (
+ this.inProfile && (
+ // Don't mute user's posts on user timeline (except reblogs)
+ (!reblog && status.user.id === this.profileUserId) ||
+ // Same as above but also allow self-reblogs
+ (reblog && reblog.user.id === this.profileUserId)
+ )
+ ) ||
+ // Don't mute statuses in muted conversation when said conversation is opened
+ (this.inConversation && status.thread_muted)
+ // No excuses if post has muted words
+ ) && !this.muteWordHits.length > 0
- return hits
+ return !this.unmuted && !excusesNotToMute && reasonsToMute
},
- muted () { return !this.unmuted && ((!(this.inProfile && this.status.user.id === this.profileUserId) && this.status.user.muted) || (!this.inConversation && this.status.thread_muted) || this.muteWordHits.length > 0) },
hideFilteredStatuses () {
return this.mergedConfig.hideFilteredStatuses
},
@@ -135,20 +153,6 @@ const Status = {
// use conversation highlight only when in conversation
return this.status.id === this.highlight
},
- // This is a bit hacky, but we want to approximate post height before rendering
- // so we count newlines (masto uses <p> for paragraphs, GS uses <br> between them)
- // as well as approximate line count by counting characters and approximating ~80
- // per line.
- //
- // Using max-height + overflow: auto for status components resulted in false positives
- // very often with japanese characters, and it was very annoying.
- tallStatus () {
- const lengthScore = this.status.statusnet_html.split(/<p|<br/).length + this.status.text.length / 80
- return lengthScore > 20
- },
- longSubject () {
- return this.status.summary.length > 900
- },
isReply () {
return !!(this.status.in_reply_to_status_id && this.status.in_reply_to_user_id)
},
@@ -178,8 +182,11 @@ const Status = {
if (this.status.user.id === this.status.attentions[i].id) {
continue
}
- const taggedUser = this.$store.getters.findUser(this.status.attentions[i].id)
- if (checkFollowing && taggedUser && taggedUser.following) {
+ // There's zero guarantee of this working. If we happen to have that user and their
+ // relationship in store then it will work, but there's kinda little chance of having
+ // them for people you're not following.
+ const relationship = this.$store.state.users.relationships[this.status.attentions[i].id]
+ if (checkFollowing && relationship && relationship.following) {
return false
}
if (this.status.attentions[i].id === this.currentUser.id) {
@@ -188,33 +195,6 @@ const Status = {
}
return this.status.attentions.length > 0
},
- hideSubjectStatus () {
- if (this.tallStatus && !this.localCollapseSubjectDefault) {
- return false
- }
- return !this.expandingSubject && this.status.summary
- },
- hideTallStatus () {
- if (this.status.summary && this.localCollapseSubjectDefault) {
- return false
- }
- if (this.showingTall) {
- return false
- }
- return this.tallStatus
- },
- showingMore () {
- return (this.tallStatus && this.showingTall) || (this.status.summary && this.expandingSubject)
- },
- nsfwClickthrough () {
- if (!this.status.nsfw) {
- return false
- }
- if (this.status.summary && this.localCollapseSubjectDefault) {
- return false
- }
- return true
- },
replySubject () {
if (!this.status.summary) return ''
const decodedSummary = unescape(this.status.summary)
@@ -228,83 +208,6 @@ const Status = {
return ''
}
},
- attachmentSize () {
- if ((this.mergedConfig.hideAttachments && !this.inConversation) ||
- (this.mergedConfig.hideAttachmentsInConv && this.inConversation) ||
- (this.status.attachments.length > this.maxThumbnails)) {
- return 'hide'
- } else if (this.compact) {
- return 'small'
- }
- return 'normal'
- },
- galleryTypes () {
- if (this.attachmentSize === 'hide') {
- return []
- }
- return this.mergedConfig.playVideosInModal
- ? ['image', 'video']
- : ['image']
- },
- galleryAttachments () {
- return this.status.attachments.filter(
- file => fileType.fileMatchesSomeType(this.galleryTypes, file)
- )
- },
- nonGalleryAttachments () {
- return this.status.attachments.filter(
- file => !fileType.fileMatchesSomeType(this.galleryTypes, file)
- )
- },
- hasImageAttachments () {
- return this.status.attachments.some(
- file => fileType.fileType(file.mimetype) === 'image'
- )
- },
- hasVideoAttachments () {
- return this.status.attachments.some(
- file => fileType.fileType(file.mimetype) === 'video'
- )
- },
- maxThumbnails () {
- return this.mergedConfig.maxThumbnails
- },
- postBodyHtml () {
- const html = this.status.statusnet_html
-
- if (this.mergedConfig.greentext) {
- try {
- if (html.includes('&gt;')) {
- // This checks if post has '>' at the beginning, excluding mentions so that @mention >impying works
- return processHtml(html, (string) => {
- if (string.includes('&gt;') &&
- string
- .replace(/<[^>]+?>/gi, '') // remove all tags
- .replace(/@\w+/gi, '') // remove mentions (even failed ones)
- .trim()
- .startsWith('&gt;')) {
- return `<span class='greentext'>${string}</span>`
- } else {
- return string
- }
- })
- } else {
- return html
- }
- } catch (e) {
- console.err('Failed to process status html', e)
- return html
- }
- } else {
- return html
- }
- },
- contentHtml () {
- if (!this.status.summary_html) {
- return this.postBodyHtml
- }
- return this.status.summary_html + '<br />' + this.postBodyHtml
- },
combinedFavsAndRepeatsUsers () {
// Use the status from the global status repository since favs and repeats are saved in it
const combinedUsers = [].concat(
@@ -313,9 +216,6 @@ const Status = {
)
return uniqBy(combinedUsers, 'id')
},
- ownStatus () {
- return this.status.user.id === this.currentUser.id
- },
tags () {
return this.status.tags.filter(tagObj => tagObj.hasOwnProperty('name')).map(tagObj => tagObj.name).join(' ')
},
@@ -329,21 +229,18 @@ const Status = {
})
},
components: {
- Attachment,
FavoriteButton,
ReactButton,
RetweetButton,
ExtraButtons,
PostStatusForm,
- Poll,
UserCard,
UserAvatar,
- Gallery,
- LinkPreview,
AvatarList,
Timeago,
StatusPopover,
- EmojiReactions
+ EmojiReactions,
+ StatusContent
},
methods: {
visibilityIcon (visibility) {
@@ -364,32 +261,6 @@ const Status = {
clearError () {
this.error = undefined
},
- linkClicked (event) {
- const target = event.target.closest('.status-content a')
- if (target) {
- if (target.className.match(/mention/)) {
- const href = target.href
- const attn = this.status.attentions.find(attn => mentionMatchesUrl(attn, href))
- if (attn) {
- event.stopPropagation()
- event.preventDefault()
- const link = this.generateUserProfileLink(attn.id, attn.screen_name)
- this.$router.push(link)
- return
- }
- }
- if (target.rel.match(/(?:^|\s)tag(?:$|\s)/) || target.className.match(/hashtag/)) {
- // Extract tag name from link url
- const tag = extractTagFromUrl(target.href)
- if (tag) {
- const link = this.generateTagLink(tag)
- this.$router.push(link)
- return
- }
- }
- window.open(target.href, '_blank')
- }
- },
toggleReplying () {
this.replying = !this.replying
},
@@ -407,26 +278,8 @@ const Status = {
toggleUserExpanded () {
this.userExpanded = !this.userExpanded
},
- toggleShowMore () {
- if (this.showingTall) {
- this.showingTall = false
- } else if (this.expandingSubject && this.status.summary) {
- this.expandingSubject = false
- } else if (this.hideTallStatus) {
- this.showingTall = true
- } else if (this.hideSubjectStatus && this.status.summary) {
- this.expandingSubject = true
- }
- },
generateUserProfileLink (id, name) {
return generateProfileLink(id, name, this.$store.state.instance.restrictedNicknames)
- },
- generateTagLink (tag) {
- return `/tag/${tag}`
- },
- setMedia () {
- const attachments = this.attachmentSize === 'hide' ? this.status.attachments : this.galleryAttachments
- return () => this.$store.dispatch('setMedia', attachments)
}
},
watch: {