app/templates/components/stream-feed/items/post.hbs
{{! We have to check `post` here due to Stream & development environments }}
{{#if post.id}}
<div class="stream-item-wrapper col-sm-12">
{{! Post Meta }}
{{#if (has-feature "feed_reasons")}}
{{#if (and post.media (eq activity.reason "media"))}}
<div class="stream-item--meta-block">
{{t "feeds.post.meta.media" media=post.media.computedTitle}}
</div>
{{/if}}
{{/if}}
{{! Post Header }}
<div class="stream-item--title-block">
{{! Pinned Post Indicator }}
{{#if isPinnedPost}}
<span class="pinned-indicator pull-xs-right">
{{svg-jar "pin"}}
{{t "components.stream-feed.post.pinned"}}
</span>
{{/if}}
{{! Avatar(s) }}
<span class="avatar-block">
<a href={{href-to "users.index" post.user}} class="author-avatar" onclick={{action "trackEngagement" "click"}}>
{{lazy-image src=(image post.user.avatar "medium")}}
</a>
{{#if post.targetUser}}
{{#unless (eq post.targetUser.id userId)}}
<a href={{href-to "users.index" post.targetUser}} class="author-avatar recipient-avatar" onclick={{action "trackEngagement" "click"}}>
{{lazy-image src=(image post.targetUser.avatar "medium")}}
</a>
{{/unless}}
{{/if}}
{{#if post.targetGroup}}
{{#unless kitsuGroup}}
<a href={{href-to "groups.group.group-page.index" post.targetGroup.slug}} class="author-group-avatar recipient-avatar" onclick={{action "trackEngagement" "click"}}>
{{lazy-image src=(image post.targetGroup.avatar "medium")}}
</a>
{{/unless}}
{{/if}}
</span>
{{! Author(s) }}
<div class="author-info">
<a class="author-name" href={{href-to "users.index" post.user}} onclick={{action "trackEngagement" "click"}}>
{{post.user.name}}
</a>
{{user-badge post.user}}
{{#if post.targetUser}}
{{#unless (eq post.targetUser.id userId)}}
<span class="recipient-info">
<small>{{t "components.stream-feed.post.to"}}</small>
<a href={{href-to "users.index" post.targetUser}} class="author-name" onclick={{action "trackEngagement" "click"}}>
{{post.targetUser.name}}
</a>
{{user-badge post.targetUser}}
</span>
{{/unless}}
{{/if}}
{{#if post.targetGroup}}
{{#unless kitsuGroup}}
<span class="recipient-info">
<small>to</small>
<a href={{href-to "groups.group.group-page.index" post.targetGroup.slug}} class="author-name" onclick={{action "trackEngagement" "click"}}>
{{post.targetGroup.name}}
</a>
<span class="tag tag-default role-tag">{{t "components.stream-feed.post.group"}}</span>
</span>
{{/unless}}
{{/if}}
{{! Timestamp }}
<a href={{href-to "posts" post.id}} onclick={{action "trackEngagement" "click"}}>
<small class="secondary-text">
{{moment-from-now post.createdAt interval=60000}}
{{#if postEdited}}
· {{t "components.stream-feed.post.edited"}} {{moment-from-now post.editedAt interval=60000}}
{{/if}}
</small>
</a>
</div>
</div>
{{! Post Content }}
<div class="stream-content">
{{#if isHidden}}
{{#if (and post.spoiler post.nsfw)}}
<div class="combo-gate">
<a href="#" {{action "toggleHidden"}}>
<div class="gate--label">
{{t "components.stream-feed.post.gate.spoiler-nsfw"}}
</div>
<div class="gate--hover">
{{t "components.stream-feed.post.gate.hover.nsfw"}}
</div>
</a>
</div>
{{else}}
{{#if post.nsfw}}
<div class="nsfw-gate">
<a href="#" {{action "toggleHidden"}}>
<div class="gate--label">{{t "components.stream-feed.post.gate.nsfw"}}</div>
<div class="gate--hover">{{t "components.stream-feed.post.gate.hover.nsfw"}}</div>
</a>
</div>
{{/if}}
{{#if post.spoiler}}
<div class="spoiler-gate">
<a href="#" {{action "toggleHidden"}}>
<div class="gate--label">
{{t "components.stream-feed.post.gate.spoiler"}}
</div>
<div class="gate--hover">
{{t "components.stream-feed.post.gate.hover.spoiler"}}
</div>
</a>
</div>
{{/if}}
{{/if}}
{{else}}
{{#if post.contentFormatted}}
<span class="stream-content-post full-post">
{{#read-more text=(format-content post.contentFormatted) length=700 maxLines=(if (or isPinnedPost isPermalink) Infinity 50) isHTML=true as |rm|}}
{{#if rm.wasTruncated}}
<div class="view-more">
<a href="#" {{action rm.toggleVisibility}}>
{{#if rm.isTruncated}}
{{t "feeds.post.more"}}
{{else}}
{{t "feeds.post.less"}}
{{/if}}
</a>
</div>
{{/if}}
{{/read-more}}
</span>
{{/if}}
{{! uploads }}
{{#if post.uploads}}
{{stream-feed/items/post/uploads-grid uploads=post.uploads}}
{{else if (not (is-object-empty post.embed))}}
{{stream-feed/items/post/embed embed=post.embed embedUrl=post.embedUrl}}
{{/if}}
{{/if}}
{{! Tagged Media }}
{{#if (and post.media (or (not post.media.nsfw) (not isHidden)))}}
<div class="tagged-media--wrapper">
<div class="tagged-media row">
<div class="stream-item--media col-xs-1">
<a href={{href-to (concat post.media.modelType ".show") post.media}}>
{{lazy-image src=(image post.media.posterImage "small")}}
</a>
</div>
<div class="col-sm no-padding-left">
<div class="stream-item--title-block">
<div class="author-info">
<a class="author-name" href={{href-to (concat post.media.modelType ".show") post.media}}>
{{post.media.computedTitle}}
</a>
{{#if post.spoiledUnit}}
—
<a class="author-name" href={{href-to (concat post.media.modelType ".show." post.spoiledUnit.modelType "s.show") post.media.slug post.spoiledUnit.number}}>
{{t "feeds.post.spoilers" type=post.media.modelType num=post.spoiledUnit.number}} {{postUnitText}}
</a>
{{/if}}
{{#if post.media.description}}
<small class="secondary-text">
<div class="media-tag-description">
{{truncate post.media.description 150}}
</div>
</small>
{{/if}}
</div>
</div>
</div>
</div>
</div>
{{/if}}
</div>
{{! Post Likes -- Don't load until we have entered viewport }}
<div class="stream-item-activity">
{{likeable-resource
resource=post
likesCount=post.postLikesCount
likesCountUpdate=(action (mut post.postLikesCount))
onCreate=(action "likeCreated")
showUsers=true
}}
</div>
<div class="stream-item-options">
{{! Comments Count }}
{{#if (and isHidden post.commentsCount)}}
<span class="stream-item-comments-count">
{{svg-jar "comment"}}
{{post.commentsCount}}
</span>
{{/if}}
{{! Dropdown }}
<span class="more-wrapper">
<a href="#" class="more-drop" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
{{svg-jar "more"}}
</a>
<div class="dropdown-menu dropdown-menu-right">
{{! Copy Permalink }}
<a class="dropdown-item" href="#" data-clipboard-text={{concat host (href-to "posts" post.id)}} {{action "trackEngagement" "click"}}>
{{t "components.stream-feed.post.link"}}
</a>
{{! Follow/Unfollow }}
{{#if (and session.hasUser (not (is-self post.user)))}}
<a class="dropdown-item" href="#" {{action "followPost"}}>
{{#if isFollowingPost}}
{{t "components.stream-feed.post.unfollow"}}
{{else}}
{{t "components.stream-feed.post.follow"}}
{{/if}}
</a>
{{/if}}
{{! Hiding }}
{{#if canHide}}
{{! Group Post Hiding }}
{{#if post.targetGroup}}
<a class="dropdown-item" href="#" {{action (toggle "hideGroupModalOpened" this)}}>
<div>{{t "groups.hide-posts.text" group=post.targetGroup.name}}</div>
<div class="option-info">{{t "groups.hide-posts.info"}}</div>
</a>
{{#if hideGroupModalOpened}}
{{to-elsewhere named="modal" send=(component "modals/confirm-action"
onConfirm=(action "hideGroup" post.targetGroup)
onClose=(toggle-action "hideGroupModalOpened" this)
)}}
{{/if}}
{{/if}}
{{! User Post Hiding }}
{{#if (and (not post.targetGroup) (and session.hasUser (not (is-self post.user))))}}
<a class="dropdown-item" href="#" {{action (toggle "hideUserModalOpened" this)}}>
<div>{{t "users.hide-posts.text" user=post.user.name}}</div>
<div class="option-info">{{t "users.hide-posts.info"}}</div>
</a>
{{#if hideUserModalOpened}}
{{to-elsewhere named="modal" send=(component "modals/confirm-action"
onConfirm=(action "hideUser" post.user)
onClose=(toggle-action "hideUserModalOpened" this)
)}}
{{/if}}
{{/if}}
{{/if}}
{{! Media Ignore }}
{{#if (and (or canHideMedia (eq activity.reason "media")) post.media)}}
<a class="dropdown-item" href="#" {{action (toggle "mediaIgnoreModalOpened" this)}}>
<div>{{t "media.hide-posts.text" media=post.media.computedTitle}}</div>
<div class="option-info">{{t "media.hide-posts.info" type=(capitalize post.media.modelType)}}</div>
</a>
{{#if mediaIgnoreModalOpened}}
{{to-elsewhere named="modal" send=(component "modals/confirm-action"
onConfirm=(action "ignoreMedia" post.media)
onClose=(toggle-action "mediaIgnoreModalOpened" this)
)}}
{{/if}}
{{/if}}
{{! Re-hide the post }}
{{#if (or post.spoiler post.nsfw)}}
{{#if isHidden}}
<a class="dropdown-item" href="#" {{action "toggleHidden"}}>{{t "components.stream-feed.post.show"}}</a>
{{else}}
<a class="dropdown-item" href="#" {{action "toggleHidden"}}>{{t "components.stream-feed.post.hide"}}</a>
{{/if}}
{{/if}}
{{! Editing/Deleting Options }}
{{#if canEditPost}}
<a class="dropdown-item" href="#" {{action (toggle "editModalOpened" this)}}>{{t "components.stream-feed.post.edit"}}</a>
{{#if editModalOpened}}
{{to-elsewhere named="modal" send=(component "stream-feed/edit-post"
post=post
unitNumber=post.spoiledUnit.number
onClose=(toggle-action "editModalOpened" this)
)}}
{{/if}}
<a class="dropdown-item" href="#" {{action (toggle "deleteModalOpened" this)}}>{{t "components.stream-feed.post.delete"}}</a>
{{#if deleteModalOpened}}
{{to-elsewhere named="modal" send=(component "modals/confirm-action"
onConfirm=(action "deletePost")
onClose=(toggle-action "deleteModalOpened" this)
)}}
{{/if}}
{{! Pin Post }}
{{#if (is-self post.user)}}
{{#if (eq session.account.pinnedPost.id post.id)}}
<a class="dropdown-item" href="#" {{action (toggle "unpinModalOpened" this)}}>
{{t "components.stream-feed.post.unpin"}}
</a>
{{#if unpinModalOpened}}
{{to-elsewhere named="modal" send=(component "modals/confirm-action"
onConfirm=(queue (action "pinOrUnpinPost" null) (toggle-action "unpinModalOpened" this))
onClose=(toggle-action "unpinModalOpened" this)
title="Unpin Post from Profile"
text="Do you really want to unpin this post from your profile?"
)}}
{{/if}}
{{else}}
<a class="dropdown-item" href="#" {{action (toggle "pinModalOpened" this)}}>
{{t "components.stream-feed.post.pin"}}
</a>
{{#if pinModalOpened}}
{{to-elsewhere named="modal" send=(component "modals/confirm-action"
onConfirm=(queue (action "pinOrUnpinPost" post) (toggle-action "pinModalOpened" this))
onClose=(toggle-action "pinModalOpened" this)
title=(t "components.stream-feed.post.pin")
text=(t "components.stream-feed.post.pin-text")
)}}
{{/if}}
{{/if}}
{{/if}}
{{/if}}
{{! Reporting/Blocking Options }}
{{#if (and session.hasUser (not (is-self post.user)))}}
<a class="dropdown-item" href="#" {{action (toggle "reportingPost" this)}}>{{t "components.stream-feed.post.report"}}</a>
{{#if reportingPost}}
{{to-elsewhere named="modal" send=(component "modals/report-content"
content=post
group=post.targetGroup
onClose=(toggle-action "reportingPost" this)
)}}
{{/if}}
<a class="dropdown-item" href="#" {{action (toggle "blockUserModal" this)}}>{{t "components.users.block" user=post.user.name}}</a>
{{#if blockUserModal}}
{{to-elsewhere named="modal" send=(component "modals/block-user"
user=post.user
onClose=(toggle-action "blockUserModal" this)
)}}
{{/if}}
{{/if}}
</div>
</span>
</div>
</div>
{{! Post Comments }}
{{#unless isHidden}}
{{stream-feed/items/post/comments
post=post
comment=comment
isReply=isReply
readOnly=readOnly
commentSort=commentSort
isPermalinkPage=isPermalinkPage
kitsuGroupMembership=kitsuGroupMembership
isModalView=isModalView
showPostModal=(toggle-action "showPostModal" this)
countUpdate=(action (mut post.topLevelCommentsCount))
trackEngagement=(action "trackEngagement")
updateFollow=(action "updateFollow")
}}
{{/unless}}
{{/if}}
{{! Post Modal }}
{{#if showPostModal}}
{{to-elsewhere named="modal" send=(component "stream-feed/items/post/modal"
post=post
readOnly=readOnly
onClose=(toggle-action "showPostModal" this)
)}}
{{/if}}