2016-10-28 16:08:03 +00:00
import Attachment from '../attachment/attachment.vue'
2016-10-30 15:12:35 +00:00
import FavoriteButton from '../favorite_button/favorite_button.vue'
2019-11-15 14:29:25 +00:00
import ReactButton from '../react_button/react_button.vue'
2016-11-13 15:42:56 +00:00
import RetweetButton from '../retweet_button/retweet_button.vue'
2019-06-18 20:28:31 +00:00
import Poll from '../poll/poll.vue'
2019-04-12 19:35:29 +00:00
import ExtraButtons from '../extra_buttons/extra_buttons.vue'
2016-11-03 15:59:27 +00:00
import PostStatusForm from '../post_status_form/post_status_form.vue'
2019-03-05 19:01:49 +00:00
import UserCard from '../user_card/user_card.vue'
2019-02-02 19:11:36 +00:00
import UserAvatar from '../user_avatar/user_avatar.vue'
2019-01-26 15:45:03 +00:00
import Gallery from '../gallery/gallery.vue'
2019-01-27 13:47:30 +00:00
import LinkPreview from '../link-preview/link-preview.vue'
2019-04-02 02:29:45 +00:00
import AvatarList from '../avatar_list/avatar_list.vue'
2019-06-18 20:28:31 +00:00
import Timeago from '../timeago/timeago.vue'
2019-10-24 20:53:36 +00:00
import StatusPopover from '../status_popover/status_popover.vue'
2020-01-14 08:06:14 +00:00
import EmojiReactions from '../emoji_reactions/emoji_reactions.vue'
2018-12-13 16:57:11 +00:00
import generateProfileLink from 'src/services/user_profile_link_generator/user_profile_link_generator'
2019-01-26 15:45:03 +00:00
import fileType from 'src/services/file_type/file_type.service'
2019-11-13 22:18:14 +00:00
import { processHtml } from 'src/services/tiny_post_html_processor/tiny_post_html_processor.service.js'
2019-01-30 18:49:24 +00:00
import { highlightClass , highlightStyle } from '../../services/user_highlighter/user_highlighter.js'
2019-02-07 21:54:49 +00:00
import { mentionMatchesUrl , extractTagFromUrl } from 'src/services/matcher/matcher.service.js'
2019-10-24 20:53:36 +00:00
import { filter , unescape , uniqBy } from 'lodash'
2019-11-13 22:18:14 +00:00
import { mapGetters , mapState } from 'vuex'
2016-10-28 16:08:03 +00:00
2016-10-28 13:19:42 +00:00
const Status = {
2018-04-09 16:43:31 +00:00
name : 'Status' ,
2017-02-04 12:53:28 +00:00
props : [
'statusoid' ,
2019-05-07 01:36:55 +00:00
'expandable' ,
2017-03-09 08:19:40 +00:00
'inConversation' ,
2017-04-12 15:25:19 +00:00
'focused' ,
2017-05-31 08:47:18 +00:00
'highlight' ,
2017-06-04 20:58:15 +00:00
'compact' ,
2018-04-09 16:43:31 +00:00
'replies' ,
2019-03-02 16:35:38 +00:00
'isPreview' ,
2018-04-09 16:43:31 +00:00
'noHeading' ,
2019-04-30 15:06:22 +00:00
'inlineExpanded' ,
2019-09-13 19:34:17 +00:00
'showPinned' ,
2019-11-25 17:25:01 +00:00
'inProfile' ,
'profileUserId'
2017-02-04 12:53:28 +00:00
] ,
2018-08-20 01:59:06 +00:00
data ( ) {
return {
2019-03-11 20:24:37 +00:00
replying : false ,
2018-08-20 01:59:06 +00:00
unmuted : false ,
userExpanded : false ,
2019-01-28 19:59:17 +00:00
showingTall : this . inConversation && this . focused ,
2019-02-04 14:28:14 +00:00
showingLongSubject : false ,
2019-04-07 15:38:16 +00:00
error : null ,
2019-11-13 22:41:14 +00:00
// not as computed because it sets the initial state which will be changed later
2019-11-13 22:52:38 +00:00
expandingSubject : ! this . $store . getters . mergedConfig . collapseMessageWithSubject
2018-08-20 01:59:06 +00:00
}
} ,
2016-10-28 16:08:03 +00:00
computed : {
2018-10-21 17:04:23 +00:00
localCollapseSubjectDefault ( ) {
2019-09-29 19:33:15 +00:00
return this . mergedConfig . collapseMessageWithSubject
2018-10-21 17:04:23 +00:00
} ,
2017-04-09 13:53:23 +00:00
muteWords ( ) {
2019-09-29 19:33:15 +00:00
return this . mergedConfig . muteWords
2017-04-09 13:53:23 +00:00
} ,
2018-06-18 08:36:58 +00:00
repeaterClass ( ) {
const user = this . statusoid . user
2018-06-19 13:17:50 +00:00
return highlightClass ( user )
2018-06-18 08:36:58 +00:00
} ,
2018-04-25 14:35:25 +00:00
userClass ( ) {
2018-06-18 08:36:58 +00:00
const user = this . retweet ? ( this . statusoid . retweeted _status . user ) : this . statusoid . user
2018-06-19 13:17:50 +00:00
return highlightClass ( user )
2018-06-18 08:36:58 +00:00
} ,
2018-12-04 18:49:00 +00:00
deleted ( ) {
2018-12-04 18:45:08 +00:00
return this . statusoid . deleted
} ,
2018-06-18 08:36:58 +00:00
repeaterStyle ( ) {
const user = this . statusoid . user
2019-09-29 19:33:15 +00:00
const highlight = this . mergedConfig . highlight
2018-08-05 02:18:04 +00:00
return highlightStyle ( highlight [ user . screen _name ] )
2018-06-18 08:36:58 +00:00
} ,
userStyle ( ) {
2018-08-05 02:41:37 +00:00
if ( this . noHeading ) return
2018-06-18 08:36:58 +00:00
const user = this . retweet ? ( this . statusoid . retweeted _status . user ) : this . statusoid . user
2019-09-29 19:33:15 +00:00
const highlight = this . mergedConfig . highlight
2018-08-05 02:18:04 +00:00
return highlightStyle ( highlight [ user . screen _name ] )
2018-04-25 14:35:25 +00:00
} ,
2017-03-04 20:25:59 +00:00
hideAttachments ( ) {
2019-09-29 19:33:15 +00:00
return ( this . mergedConfig . hideAttachments && ! this . inConversation ) ||
( this . mergedConfig . hideAttachmentsInConv && this . inConversation )
2017-03-04 20:25:59 +00:00
} ,
2019-01-22 20:57:51 +00:00
userProfileLink ( ) {
return this . generateUserProfileLink ( this . status . user . id , this . status . user . screen _name )
} ,
replyProfileLink ( ) {
if ( this . isReply ) {
2019-01-30 14:57:19 +00:00
return this . generateUserProfileLink ( this . status . in _reply _to _user _id , this . replyToName )
2019-01-22 20:57:51 +00:00
}
} ,
2016-10-28 16:08:03 +00:00
retweet ( ) { return ! ! this . statusoid . retweeted _status } ,
2019-02-01 22:40:06 +00:00
retweeter ( ) { return this . statusoid . user . name || this . statusoid . user . screen _name } ,
2018-08-09 09:52:34 +00:00
retweeterHtml ( ) { return this . statusoid . user . name _html } ,
2019-02-03 19:08:04 +00:00
retweeterProfileLink ( ) { return this . generateUserProfileLink ( this . statusoid . user . id , this . statusoid . user . screen _name ) } ,
2016-10-28 16:08:03 +00:00
status ( ) {
if ( this . retweet ) {
return this . statusoid . retweeted _status
} else {
return this . statusoid
}
2016-11-06 19:45:26 +00:00
} ,
2019-04-09 15:45:33 +00:00
statusFromGlobalRepository ( ) {
// NOTE: Consider to replace status with statusFromGlobalRepository
return this . $store . state . statuses . allStatusesObject [ this . status . id ]
} ,
2016-11-06 19:45:26 +00:00
loggedIn ( ) {
2019-11-13 22:18:14 +00:00
return ! ! this . currentUser
2017-02-13 23:01:50 +00:00
} ,
2017-04-09 13:53:23 +00:00
muteWordHits ( ) {
const statusText = this . status . text . toLowerCase ( )
2019-07-20 17:06:54 +00:00
const statusSummary = this . status . summary . toLowerCase ( )
2017-04-09 13:53:23 +00:00
const hits = filter ( this . muteWords , ( muteWord ) => {
2019-07-20 17:06:54 +00:00
return statusText . includes ( muteWord . toLowerCase ( ) ) || statusSummary . includes ( muteWord . toLowerCase ( ) )
2017-04-09 13:53:23 +00:00
} )
return hits
} ,
2019-11-25 17:25:01 +00:00
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 ) } ,
2019-02-06 18:18:13 +00:00
hideFilteredStatuses ( ) {
2019-09-29 19:33:15 +00:00
return this . mergedConfig . hideFilteredStatuses
2019-02-06 18:18:13 +00:00
} ,
2019-02-08 12:25:56 +00:00
hideStatus ( ) {
2019-02-08 13:17:20 +00:00
return ( this . hideReply || this . deleted ) || ( this . muted && this . hideFilteredStatuses )
2019-02-08 12:25:56 +00:00
} ,
2017-04-12 15:25:19 +00:00
isFocused ( ) {
// retweet or root of an expanded conversation
2017-04-12 16:07:55 +00:00
if ( this . focused ) {
2017-04-12 15:25:19 +00:00
return true
2017-04-12 16:07:55 +00:00
} else if ( ! this . inConversation ) {
2017-04-12 15:25:19 +00:00
return false
2017-04-12 16:07:55 +00:00
}
// use conversation highlight only when in conversation
return this . status . id === this . highlight
2018-04-09 16:43:31 +00:00
} ,
// 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.
2018-08-20 01:59:06 +00:00
tallStatus ( ) {
const lengthScore = this . status . statusnet _html . split ( /<p|<br/ ) . length + this . status . text . length / 80
return lengthScore > 20
} ,
2019-02-04 14:28:14 +00:00
longSubject ( ) {
return this . status . summary . length > 900
2019-02-04 04:47:26 +00:00
} ,
2018-08-24 19:04:26 +00:00
isReply ( ) {
2019-01-27 09:31:23 +00:00
return ! ! ( this . status . in _reply _to _status _id && this . status . in _reply _to _user _id )
2018-08-24 19:04:26 +00:00
} ,
2019-01-22 20:57:51 +00:00
replyToName ( ) {
2019-03-08 23:34:15 +00:00
if ( this . status . in _reply _to _screen _name ) {
2019-01-24 17:27:20 +00:00
return this . status . in _reply _to _screen _name
2019-03-08 23:34:15 +00:00
} else {
2019-03-08 23:36:35 +00:00
const user = this . $store . getters . findUser ( this . status . in _reply _to _user _id )
return user && user . screen _name
2019-01-22 20:57:51 +00:00
}
} ,
2018-08-24 19:04:26 +00:00
hideReply ( ) {
2019-09-29 19:33:15 +00:00
if ( this . mergedConfig . replyVisibility === 'all' ) {
2018-08-24 19:04:26 +00:00
return false
}
2019-05-06 20:17:29 +00:00
if ( this . inConversation || ! this . isReply ) {
2018-08-24 19:04:26 +00:00
return false
}
2019-11-13 22:18:14 +00:00
if ( this . status . user . id === this . currentUser . id ) {
2018-08-24 19:04:26 +00:00
return false
}
2019-01-17 20:44:31 +00:00
if ( this . status . type === 'retweet' ) {
2018-08-24 19:04:26 +00:00
return false
}
2019-09-29 19:33:15 +00:00
const checkFollowing = this . mergedConfig . replyVisibility === 'following'
2018-08-24 19:04:26 +00:00
for ( var i = 0 ; i < this . status . attentions . length ; ++ i ) {
if ( this . status . user . id === this . status . attentions [ i ] . id ) {
continue
}
2019-07-07 19:23:04 +00:00
const taggedUser = this . $store . getters . findUser ( this . status . attentions [ i ] . id )
if ( checkFollowing && taggedUser && taggedUser . following ) {
2018-08-24 19:04:26 +00:00
return false
}
2019-11-13 22:18:14 +00:00
if ( this . status . attentions [ i ] . id === this . currentUser . id ) {
2018-08-24 19:04:26 +00:00
return false
}
}
return this . status . attentions . length > 0
} ,
2020-02-24 23:10:15 +00:00
// 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.
mightHideBecauseSubject ( ) {
return this . status . summary && ( ! this . tallStatus || this . localCollapseSubjectDefault )
} ,
mightHideBecauseTall ( ) {
return this . tallStatus && ( ! this . status . summary || ! this . localCollapseSubjectDefault )
} ,
2018-08-20 02:41:40 +00:00
hideSubjectStatus ( ) {
2020-02-24 23:10:15 +00:00
return this . mightHideBecauseSubject && ! this . expandingSubject
2018-08-20 01:59:06 +00:00
} ,
2018-04-09 16:43:31 +00:00
hideTallStatus ( ) {
2020-02-24 23:10:15 +00:00
return this . mightHideBecauseTall && ! this . showingTall
2018-08-20 01:59:06 +00:00
} ,
showingMore ( ) {
2020-02-24 23:10:15 +00:00
return ( this . mightHideBecauseTall && this . showingTall ) || ( this . mightHideBecauseSubject && this . expandingSubject )
2018-04-09 16:43:31 +00:00
} ,
2018-08-25 23:21:54 +00:00
nsfwClickthrough ( ) {
if ( ! this . status . nsfw ) {
return false
}
2018-10-21 17:04:23 +00:00
if ( this . status . summary && this . localCollapseSubjectDefault ) {
2018-08-25 23:21:54 +00:00
return false
}
return true
} ,
2018-08-26 00:50:11 +00:00
replySubject ( ) {
2018-09-25 12:21:47 +00:00
if ( ! this . status . summary ) return ''
2019-02-09 12:13:52 +00:00
const decodedSummary = unescape ( this . status . summary )
2019-09-29 19:33:15 +00:00
const behavior = this . mergedConfig . subjectLineBehavior
2019-02-08 16:25:53 +00:00
const startsWithRe = decodedSummary . match ( /^re[: ]/i )
2019-07-06 21:54:17 +00:00
if ( ( behavior !== 'noop' && startsWithRe ) || behavior === 'masto' ) {
2019-02-08 16:25:53 +00:00
return decodedSummary
2018-09-25 12:16:26 +00:00
} else if ( behavior === 'email' ) {
2019-02-08 16:25:53 +00:00
return 're: ' . concat ( decodedSummary )
2018-09-25 12:16:26 +00:00
} else if ( behavior === 'noop' ) {
return ''
2018-08-26 00:50:11 +00:00
}
} ,
2018-04-09 16:43:31 +00:00
attachmentSize ( ) {
2019-09-29 19:33:15 +00:00
if ( ( this . mergedConfig . hideAttachments && ! this . inConversation ) ||
( this . mergedConfig . hideAttachmentsInConv && this . inConversation ) ||
2019-02-27 14:38:58 +00:00
( this . status . attachments . length > this . maxThumbnails ) ) {
2018-04-09 16:43:31 +00:00
return 'hide'
} else if ( this . compact ) {
return 'small'
}
return 'normal'
2019-01-26 15:45:03 +00:00
} ,
galleryTypes ( ) {
if ( this . attachmentSize === 'hide' ) {
return [ ]
}
2019-09-29 19:33:15 +00:00
return this . mergedConfig . playVideosInModal
2019-01-31 19:19:41 +00:00
? [ 'image' , 'video' ]
: [ 'image' ]
2019-01-26 15:45:03 +00:00
} ,
galleryAttachments ( ) {
return this . status . attachments . filter (
file => fileType . fileMatchesSomeType ( this . galleryTypes , file )
)
} ,
nonGalleryAttachments ( ) {
return this . status . attachments . filter (
file => ! fileType . fileMatchesSomeType ( this . galleryTypes , file )
)
2019-02-27 14:38:58 +00:00
} ,
2020-02-08 21:01:01 +00:00
hasImageAttachments ( ) {
return this . status . attachments . some (
file => fileType . fileType ( file . mimetype ) === 'image'
)
} ,
hasVideoAttachments ( ) {
return this . status . attachments . some (
file => fileType . fileType ( file . mimetype ) === 'video'
)
} ,
2019-02-27 14:38:58 +00:00
maxThumbnails ( ) {
2019-09-29 19:33:15 +00:00
return this . mergedConfig . maxThumbnails
2019-04-01 16:54:34 +00:00
} ,
2019-11-13 22:18:14 +00:00
postBodyHtml ( ) {
const html = this . status . statusnet _html
2019-11-13 22:47:20 +00:00
if ( this . mergedConfig . greentext ) {
try {
if ( html . includes ( '>' ) ) {
// This checks if post has '>' at the beginning, excluding mentions so that @mention >impying works
return processHtml ( html , ( string ) => {
if ( string . includes ( '>' ) &&
string
2019-11-13 22:52:38 +00:00
. replace ( /<[^>]+?>/gi , '' ) // remove all tags
. replace ( /@\w+/gi , '' ) // remove mentions (even failed ones)
. trim ( )
. startsWith ( '>' ) ) {
2019-11-13 22:47:20 +00:00
return ` <span class='greentext'> ${ string } </span> `
} else {
return string
}
} )
} else {
return html
}
} catch ( e ) {
console . err ( 'Failed to process status html' , e )
2019-11-13 22:18:14 +00:00
return html
}
2019-11-13 22:47:20 +00:00
} else {
2019-11-13 22:18:14 +00:00
return html
}
} ,
2019-04-01 16:54:34 +00:00
contentHtml ( ) {
2019-04-01 17:01:28 +00:00
if ( ! this . status . summary _html ) {
2019-11-13 22:18:14 +00:00
return this . postBodyHtml
2019-04-01 17:01:28 +00:00
}
2019-11-13 22:18:14 +00:00
return this . status . summary _html + '<br />' + this . postBodyHtml
2019-04-02 02:29:45 +00:00
} ,
2019-05-01 14:33:56 +00:00
combinedFavsAndRepeatsUsers ( ) {
2019-04-09 15:45:33 +00:00
// Use the status from the global status repository since favs and repeats are saved in it
2019-05-01 14:33:56 +00:00
const combinedUsers = [ ] . concat (
2019-04-29 19:36:39 +00:00
this . statusFromGlobalRepository . favoritedBy ,
this . statusFromGlobalRepository . rebloggedBy
)
2019-05-01 14:33:56 +00:00
return uniqBy ( combinedUsers , 'id' )
2019-04-04 16:56:13 +00:00
} ,
ownStatus ( ) {
2019-11-13 22:18:14 +00:00
return this . status . user . id === this . currentUser . id
2019-05-20 19:23:36 +00:00
} ,
tags ( ) {
return this . status . tags . filter ( tagObj => tagObj . hasOwnProperty ( 'name' ) ) . map ( tagObj => tagObj . name ) . join ( ' ' )
2019-07-09 13:50:23 +00:00
} ,
hidePostStats ( ) {
2019-09-29 19:33:15 +00:00
return this . mergedConfig . hidePostStats
} ,
2019-11-13 22:18:14 +00:00
... mapGetters ( [ 'mergedConfig' ] ) ,
... mapState ( {
betterShadow : state => state . interface . browserSupport . cssFilter ,
currentUser : state => state . users . currentUser
} )
2016-10-28 16:08:03 +00:00
} ,
components : {
2016-10-30 15:12:35 +00:00
Attachment ,
2016-11-03 15:59:27 +00:00
FavoriteButton ,
2019-11-15 14:29:25 +00:00
ReactButton ,
2016-11-13 15:42:56 +00:00
RetweetButton ,
2019-04-12 19:35:29 +00:00
ExtraButtons ,
2017-02-16 14:58:49 +00:00
PostStatusForm ,
2019-06-18 20:28:31 +00:00
Poll ,
2019-03-05 19:01:49 +00:00
UserCard ,
2019-02-02 19:11:36 +00:00
UserAvatar ,
2019-01-30 18:49:24 +00:00
Gallery ,
2019-04-02 02:29:45 +00:00
LinkPreview ,
2019-06-18 20:28:31 +00:00
AvatarList ,
2019-10-24 20:53:36 +00:00
Timeago ,
2020-01-14 08:06:14 +00:00
StatusPopover ,
EmojiReactions
2016-11-03 15:59:27 +00:00
} ,
methods : {
2018-05-21 22:01:33 +00:00
visibilityIcon ( visibility ) {
switch ( visibility ) {
case 'private' :
return 'icon-lock'
case 'unlisted' :
return 'icon-lock-open-alt'
case 'direct' :
return 'icon-mail-alt'
default :
return 'icon-globe'
2018-05-20 16:28:01 +00:00
}
} ,
2019-04-12 19:35:29 +00:00
showError ( error ) {
this . error = error
2019-04-27 13:36:10 +00:00
} ,
clearError ( ) {
this . error = undefined
2019-04-12 19:35:29 +00:00
} ,
2019-01-30 17:15:35 +00:00
linkClicked ( event ) {
2019-07-24 00:59:37 +00:00
const target = event . target . closest ( '.status-content a' )
2019-07-23 19:43:03 +00:00
if ( target ) {
2019-01-30 17:15:35 +00:00
if ( target . className . match ( /mention/ ) ) {
2019-02-07 21:54:49 +00:00
const href = target . href
2019-01-30 17:15:35 +00:00
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
}
2019-02-07 21:54:49 +00:00
}
2019-08-13 17:11:37 +00:00
if ( target . rel . match ( /(?:^|\s)tag(?:$|\s)/ ) || target . className . match ( /hashtag/ ) ) {
2019-02-07 21:54:49 +00:00
// Extract tag name from link url
const tag = extractTagFromUrl ( target . href )
if ( tag ) {
const link = this . generateTagLink ( tag )
this . $router . push ( link )
2019-02-11 14:45:22 +00:00
return
2019-02-07 21:54:49 +00:00
}
2019-01-30 17:15:35 +00:00
}
2019-02-11 14:38:12 +00:00
window . open ( target . href , '_blank' )
2017-02-19 11:58:25 +00:00
}
} ,
2016-11-03 15:59:27 +00:00
toggleReplying ( ) {
2019-03-11 20:24:37 +00:00
this . replying = ! this . replying
2017-02-04 12:53:28 +00:00
} ,
2017-06-04 20:58:15 +00:00
gotoOriginal ( id ) {
2017-11-14 06:55:21 +00:00
if ( this . inConversation ) {
2017-11-13 14:33:54 +00:00
this . $emit ( 'goto' , id )
}
2017-04-12 15:25:19 +00:00
} ,
2017-02-04 12:53:28 +00:00
toggleExpanded ( ) {
this . $emit ( 'toggleExpanded' )
2017-02-13 23:01:50 +00:00
} ,
toggleMute ( ) {
this . unmuted = ! this . unmuted
2017-02-16 14:58:49 +00:00
} ,
toggleUserExpanded ( ) {
this . userExpanded = ! this . userExpanded
2017-06-07 14:58:24 +00:00
} ,
2018-08-20 01:59:06 +00:00
toggleShowMore ( ) {
2020-02-24 23:10:15 +00:00
if ( this . mightHideBecauseTall ) {
this . showingTall = ! this . showingTall
} else if ( this . mightHideBecauseSubject ) {
this . expandingSubject = ! this . expandingSubject
2018-08-20 01:59:06 +00:00
}
2018-04-09 16:43:31 +00:00
} ,
2019-01-22 20:57:51 +00:00
generateUserProfileLink ( id , name ) {
2018-12-26 13:50:48 +00:00
return generateProfileLink ( id , name , this . $store . state . instance . restrictedNicknames )
2019-01-14 17:23:13 +00:00
} ,
2019-02-07 21:54:49 +00:00
generateTagLink ( tag ) {
return ` /tag/ ${ tag } `
} ,
2019-01-14 17:23:13 +00:00
setMedia ( ) {
2019-01-26 15:45:03 +00:00
const attachments = this . attachmentSize === 'hide' ? this . status . attachments : this . galleryAttachments
2019-01-14 17:23:13 +00:00
return ( ) => this . $store . dispatch ( 'setMedia' , attachments )
2018-08-05 02:44:02 +00:00
}
2017-04-12 15:25:19 +00:00
} ,
watch : {
2017-04-12 16:07:55 +00:00
'highlight' : function ( id ) {
if ( this . status . id === id ) {
2017-04-12 15:25:19 +00:00
let rect = this . $el . getBoundingClientRect ( )
2017-04-12 16:07:55 +00:00
if ( rect . top < 100 ) {
2019-01-30 14:38:28 +00:00
// Post is above screen, match its top to screen top
window . scrollBy ( 0 , rect . top - 100 )
} else if ( rect . height >= ( window . innerHeight - 50 ) ) {
// Post we want to see is taller than screen so match its top to screen top
window . scrollBy ( 0 , rect . top - 100 )
2017-06-04 20:58:15 +00:00
} else if ( rect . bottom > window . innerHeight - 50 ) {
2019-01-30 14:38:28 +00:00
// Post is below screen, match its bottom to screen bottom
2017-06-04 20:58:15 +00:00
window . scrollBy ( 0 , rect . bottom - window . innerHeight + 50 )
2017-04-12 16:07:55 +00:00
}
2017-04-12 15:25:19 +00:00
}
2019-06-24 09:19:43 +00:00
} ,
'status.repeat_num' : function ( num ) {
2019-06-27 12:19:35 +00:00
// refetch repeats when repeat_num is changed in any way
2019-06-24 09:19:43 +00:00
if ( this . isFocused && this . statusFromGlobalRepository . rebloggedBy && this . statusFromGlobalRepository . rebloggedBy . length !== num ) {
2019-06-27 12:14:54 +00:00
this . $store . dispatch ( 'fetchRepeats' , this . status . id )
2019-06-24 09:19:43 +00:00
}
} ,
'status.fave_num' : function ( num ) {
2019-06-27 12:19:35 +00:00
// refetch favs when fave_num is changed in any way
2019-06-24 09:19:43 +00:00
if ( this . isFocused && this . statusFromGlobalRepository . favoritedBy && this . statusFromGlobalRepository . favoritedBy . length !== num ) {
2019-06-27 12:14:54 +00:00
this . $store . dispatch ( 'fetchFavs' , this . status . id )
2019-06-24 09:19:43 +00:00
}
2017-04-12 15:25:19 +00:00
}
2018-08-27 09:51:30 +00:00
} ,
filters : {
capitalize : function ( str ) {
return str . charAt ( 0 ) . toUpperCase ( ) + str . slice ( 1 )
}
2016-10-28 16:08:03 +00:00
}
2016-10-28 13:19:42 +00:00
}
export default Status