hummingbird-me/kitsu-web

View on GitHub
app/templates/components/stream-feed/items/post.hbs

Summary

Maintainability
Test Coverage
{{! 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}}
              &middot; {{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}}