PostReactions.vue 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251
  1. <template>
  2. <div class="px-3 my-3" style="z-index:3;">
  3. <div v-if="(status.favourites_count || status.reblogs_count) && ((status.hasOwnProperty('liked_by') && status.liked_by.url) || (status.hasOwnProperty('reblogs_count') && status.reblogs_count))" class="mb-0 d-flex justify-content-between">
  4. <p v-if="!hideCounts && status.favourites_count" class="mb-2 reaction-liked-by">
  5. Liked by
  6. <span v-if="status.favourites_count == 1 && status.favourited == true" class="font-weight-bold">me</span>
  7. <span v-else>
  8. <router-link :to="'/i/web/profile/' + status.liked_by.id" class="primary font-weight-bold">{{ status.liked_by.username}}</router-link>
  9. <span v-if="status.liked_by.others || status.favourites_count > 1">
  10. and <a href="#" class="primary font-weight-bold" @click.prevent="showLikes()">{{ count(status.favourites_count - 1) }} others</a>
  11. </span>
  12. </span>
  13. </p>
  14. <p v-if="!hideCounts && status.reblogs_count" class="mb-2 reaction-liked-by">
  15. Shared by
  16. <span v-if="status.reblogs_count == 1 && status.reblogged == true" class="font-weight-bold">me</span>
  17. <a v-else class="primary font-weight-bold" href="#" @click.prevent="showShares()">
  18. {{ count(status.reblogs_count) }} {{ status.reblogs_count > 1 ? 'others' : 'other' }}
  19. </a>
  20. </p>
  21. </div>
  22. <div class="d-flex justify-content-between" style="font-size: 14px !important;">
  23. <div>
  24. <button type="button" class="btn btn-light font-weight-bold rounded-pill mr-2" @click.prevent="like()">
  25. <span v-if="status.favourited" class="primary">
  26. <i class="fas fa-heart mr-md-1 text-danger fa-lg"></i>
  27. </span>
  28. <span v-else>
  29. <i class="far fa-heart mr-md-2"></i>
  30. </span>
  31. <span v-if="likesCount && !hideCounts">
  32. {{ count(likesCount)}}
  33. <span class="d-none d-md-inline">{{ likesCount == 1 ? $t('common.like') : $t('common.likes') }}</span>
  34. </span>
  35. <span v-else>
  36. <span class="d-none d-md-inline">{{ $t('common.like') }}</span>
  37. </span>
  38. </button>
  39. <button v-if="!status.comments_disabled" type="button" class="btn btn-light font-weight-bold rounded-pill mr-2 px-3" @click="showComments()">
  40. <i class="far fa-comment mr-md-2"></i>
  41. <span v-if="replyCount && !hideCounts">
  42. {{ count(replyCount) }}
  43. <span class="d-none d-md-inline">{{ replyCount == 1 ? $t('common.comment') : $t('common.comments') }}</span>
  44. </span>
  45. <span v-else>
  46. <span class="d-none d-md-inline">{{ $t('common.comment') }}</span>
  47. </span>
  48. </button>
  49. </div>
  50. <div>
  51. <button
  52. type="button"
  53. class="btn btn-light font-weight-bold rounded-pill"
  54. :disabled="isReblogging"
  55. @click="handleReblog()">
  56. <span v-if="isReblogging">
  57. <b-spinner variant="warning" small />
  58. </span>
  59. <span v-else>
  60. <i v-if="status.reblogged == true" class="fas fa-retweet fa-lg text-warning"></i>
  61. <i v-else class="far fa-retweet"></i>
  62. <span v-if="status.reblogs_count && !hideCounts" class="ml-md-2">
  63. {{ count(status.reblogs_count) }}
  64. </span>
  65. </span>
  66. </button>
  67. <button
  68. v-if="!status.in_reply_to_id && !status.reblog_of_id"
  69. type="button"
  70. class="btn btn-light font-weight-bold rounded-pill ml-3"
  71. :disabled="isBookmarking"
  72. @click="handleBookmark()">
  73. <span v-if="isBookmarking">
  74. <b-spinner variant="warning" small />
  75. </span>
  76. <span v-else>
  77. <i v-if="status.hasOwnProperty('bookmarked_at') || (status.hasOwnProperty('bookmarked') && status.bookmarked == true)" class="fas fa-bookmark fa-lg text-warning"></i>
  78. <i v-else class="far fa-bookmark"></i>
  79. </span>
  80. </button>
  81. <button v-if="admin" type="button" class="ml-3 btn btn-light font-weight-bold rounded-pill" v-b-tooltip.hover title="Moderation Tools" @click="openModTools()">
  82. <i class="far fa-user-crown"></i>
  83. </button>
  84. </div>
  85. </div>
  86. </div>
  87. </template>
  88. <script type="text/javascript">
  89. import CommentDrawer from './CommentDrawer.vue';
  90. import ProfileHoverCard from './../profile/ProfileHoverCard.vue';
  91. export default {
  92. props: {
  93. status: {
  94. type: Object
  95. },
  96. profile: {
  97. type: Object
  98. },
  99. admin: {
  100. type: Boolean,
  101. default: false
  102. }
  103. },
  104. components: {
  105. "comment-drawer": CommentDrawer,
  106. "profile-hover-card": ProfileHoverCard
  107. },
  108. data() {
  109. return {
  110. key: 1,
  111. menuLoading: true,
  112. sensitive: false,
  113. isReblogging: false,
  114. isBookmarking: false,
  115. owner: false,
  116. license: false
  117. }
  118. },
  119. computed: {
  120. hideCounts: {
  121. get() {
  122. return this.$store.state.hideCounts == true;
  123. }
  124. },
  125. autoloadComments: {
  126. get() {
  127. return this.$store.state.autoloadComments == true;
  128. }
  129. },
  130. newReactions: {
  131. get() {
  132. return this.$store.state.newReactions;
  133. },
  134. },
  135. likesCount: function() {
  136. return this.status.favourites_count;
  137. },
  138. replyCount: function() {
  139. return this.status.reply_count;
  140. }
  141. },
  142. methods: {
  143. count(val) {
  144. return App.util.format.count(val);
  145. },
  146. like() {
  147. event.currentTarget.blur();
  148. if(this.status.favourited) {
  149. this.$emit('unlike');
  150. } else {
  151. this.$emit('like');
  152. }
  153. },
  154. showLikes() {
  155. event.currentTarget.blur();
  156. this.$emit('likes-modal');
  157. },
  158. showShares() {
  159. event.currentTarget.blur();
  160. this.$emit('shares-modal');
  161. },
  162. showComments() {
  163. event.currentTarget.blur();
  164. this.$emit('toggle-comments');
  165. },
  166. copyLink() {
  167. event.currentTarget.blur();
  168. App.util.clipboard(this.status.url);
  169. },
  170. shareToOther() {
  171. if (navigator.canShare) {
  172. navigator.share({
  173. url: this.status.url
  174. })
  175. .then(() => console.log('Share was successful.'))
  176. .catch((error) => console.log('Sharing failed', error));
  177. } else {
  178. swal('Not supported', 'Your current device does not support native sharing.', 'error');
  179. }
  180. },
  181. counterChange(type) {
  182. this.$emit('counter-change', type);
  183. },
  184. showCommentLikes(post) {
  185. this.$emit('comment-likes-modal', post);
  186. },
  187. handleReblog() {
  188. this.isReblogging = true;
  189. if(this.status.reblogged) {
  190. this.$emit('unshare');
  191. } else {
  192. this.$emit('share');
  193. }
  194. setTimeout(() => {
  195. this.isReblogging = false;
  196. }, 5000);
  197. },
  198. handleBookmark() {
  199. event.currentTarget.blur();
  200. this.isBookmarking = true;
  201. this.$emit('bookmark');
  202. setTimeout(() => {
  203. this.isBookmarking = false;
  204. }, 2000);
  205. },
  206. getStatusAvatar() {
  207. if(window._sharedData.user.id == this.status.account.id) {
  208. return window._sharedData.user.avatar;
  209. }
  210. return this.status.account.avatar;
  211. },
  212. openModTools() {
  213. this.$emit('mod-tools');
  214. }
  215. }
  216. }
  217. </script>