ThreadDisplay.vue 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188
  1. <template>
  2. <div class='thread_display'>
  3. <avatar-icon
  4. ref='avatar'
  5. :user='thread.User'
  6. size='small'
  7. class='thread_display__icon'
  8. @click='goToUser'
  9. ></avatar-icon>
  10. <div style='width: calc(100% - 3rem);' @click='goToThread'>
  11. <div class='thread_display__header'>
  12. <span class='thread_display__name'>
  13. {{thread.name}}
  14. </span>
  15. <div class='thread_display__meta_bar'>
  16. <div>
  17. By
  18. <span class='thread_display__username' ref='username'>{{threadUsername | truncateMid(25)}}</span>
  19. in
  20. <span class='thread_display__category' ref='category'>{{thread.Category.name}}</span>
  21. &middot;
  22. <span class='thread_display__date'>{{thread.createdAt | formatDate}}</span>
  23. </div>
  24. </div>
  25. </div>
  26. <div class='thread_display__replies_bar'>
  27. <div
  28. class='thread_display__latest_reply'
  29. v-if='thread.Posts.length === 2'
  30. >
  31. <span class='fa fa-reply fa-fw'></span>
  32. <span class='thread_display__latest_reply__text'>Latest reply by</span>
  33. <span class='thread_display__username'>{{replyUsername}}</span>
  34. &middot;
  35. <span class='thread_display__date'>{{thread.Posts[1].createdAt | formatDate}}</span>
  36. </div>
  37. <span style='cursor: default;' v-else>No replies</span>
  38. <div class='thread_display__replies' title='Replies to thread'>
  39. <span class='fa fa-comment-o fa-fw'></span>
  40. {{thread.postsCount - 1}}
  41. </div>
  42. </div>
  43. <div class='thread_display__content'>
  44. {{thread.Posts[0].content | stripTags | truncate(150)}}
  45. </div>
  46. </div>
  47. </div>
  48. </template>
  49. <script>
  50. import AvatarIcon from './AvatarIcon'
  51. export default {
  52. name: 'ThreadDisplay',
  53. props: ['thread'],
  54. components: {
  55. AvatarIcon
  56. },
  57. computed: {
  58. threadUsername () {
  59. if(this.thread.User) {
  60. return this.thread.User.username
  61. } else {
  62. return '[deleted]'
  63. }
  64. },
  65. replyUsername () {
  66. if(this.thread.Posts[1].User) {
  67. return this.thread.Posts[1].User.username
  68. } else {
  69. return '[deleted]'
  70. }
  71. }
  72. },
  73. methods: {
  74. goToUser () {
  75. this.$router.push('/user/' + this.thread.User.username)
  76. },
  77. goToThread () {
  78. this.$router.push('/thread/' + this.thread.slug + '/' + this.thread.id)
  79. }
  80. }
  81. }
  82. </script>
  83. <style lang='scss' scoped>
  84. @import '../assets/scss/variables.scss';
  85. .thread_display {
  86. background-color: #fff;
  87. border: thin solid $color__gray--darker;
  88. border-radius: 0.25rem;
  89. cursor: pointer;
  90. display: flex;
  91. margin-bottom: 1rem;
  92. padding: 0.75rem;
  93. position: relative;
  94. transition: background-color 0.2s, box-shadow 0.2s;
  95. &:hover {
  96. @extend .shadow_border--hover;
  97. }
  98. @at-root #{&}__icon {
  99. margin-right: 0.5rem;
  100. }
  101. @at-root #{&}__username,
  102. #{&}__category,
  103. #{&}__date {
  104. color: $color--text__primary;
  105. }
  106. @at-root #{&}__header {
  107. display: flex;
  108. justify-content: space-between;
  109. }
  110. @at-root #{&}__name {
  111. font-weight: 500;
  112. font-size: 1.25rem;
  113. overflow: hidden;
  114. text-overflow: ellipsis;
  115. line-height: 1.5rem;
  116. height: 1.5rem;
  117. }
  118. @at-root #{&}__meta_bar {
  119. color: $color--gray__darkest;
  120. flex-shrink: 0;
  121. line-height: 1.5rem;
  122. height: 1.5rem;
  123. }
  124. @at-root #{&}__replies_bar {
  125. display: flex;
  126. justify-content: space-between;
  127. }
  128. @at-root #{&}__latest_reply {
  129. color: $color--text__secondary;
  130. .fa {
  131. color: $color--text__primary;
  132. font-size: 0.75rem;
  133. }
  134. }
  135. @at-root #{&}__replies {
  136. width: 4rem;
  137. text-align: right;
  138. }
  139. @at-root #{&}__content {
  140. margin-top: 0.5rem;
  141. word-break: break-all;
  142. }
  143. }
  144. @media (max-width: 420px) {
  145. .thread_display {
  146. @at-root #{&}__header {
  147. flex-direction: column;
  148. }
  149. @at-root #{&}__meta_bar {
  150. font-size: 0.9rem;
  151. margin-bottom: 0.25rem;
  152. }
  153. @at-root #{&}__content {
  154. display: none;
  155. }
  156. @at-root #{&}__replies_bar {
  157. position: relative;
  158. left: -3.25rem;
  159. width: calc(100% + 3.25rem);
  160. }
  161. @at-root #{&}__latest_reply {
  162. .fa {
  163. margin-right: 0.25rem;
  164. }
  165. @at-root #{&}__text {
  166. display: none;
  167. }
  168. }
  169. }
  170. }
  171. </style>