1
0

PostComments.vue 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. <style type="text/css">
  2. .b-dropdown > button {
  3. padding:0 !important;
  4. }
  5. </style>
  6. <style scoped>
  7. span {
  8. font-size: 14px;
  9. }
  10. .comment-text {
  11. word-break: break-all;
  12. }
  13. .b-dropdown {
  14. padding:0 !important;
  15. }
  16. .b-dropdown < button {
  17. }
  18. .lds-ring {
  19. display: inline-block;
  20. position: relative;
  21. width: 64px;
  22. height: 64px;
  23. }
  24. .lds-ring div {
  25. box-sizing: border-box;
  26. display: block;
  27. position: absolute;
  28. width: 51px;
  29. height: 51px;
  30. margin: 6px;
  31. border: 6px solid #6c757d;
  32. border-radius: 50%;
  33. animation: lds-ring 1.2s cubic-bezier(0.5, 0, 0.5, 1) infinite;
  34. border-color: #6c757d transparent transparent transparent;
  35. }
  36. .lds-ring div:nth-child(1) {
  37. animation-delay: -0.45s;
  38. }
  39. .lds-ring div:nth-child(2) {
  40. animation-delay: -0.3s;
  41. }
  42. .lds-ring div:nth-child(3) {
  43. animation-delay: -0.15s;
  44. }
  45. @keyframes lds-ring {
  46. 0% {
  47. transform: rotate(0deg);
  48. }
  49. 100% {
  50. transform: rotate(360deg);
  51. }
  52. }
  53. </style>
  54. <template>
  55. <div>
  56. <div class="lwrapper text-center">
  57. <div class="lds-ring"><div></div><div></div><div></div><div></div></div>
  58. </div>
  59. <div class="cwrapper d-none">
  60. <p class="mb-1 text-center load-more-link"><a href="#" class="text-muted" v-on:click="loadMore">Load more comments</a></p>
  61. <div class="comments" data-min-id="0" data-max-id="0">
  62. <p class="mb-2 d-flex justify-content-between align-items-center" v-for="(comment, index) in results" :data-id="comment.id" v-bind:key="comment.id">
  63. <span class="pr-3">
  64. <span class="font-weight-bold pr-1"><bdi><a class="text-dark" :href="comment.account.url">{{comment.account.username}}</a></bdi></span>
  65. <span class="comment-text" v-html="comment.content"></span>
  66. </span>
  67. <b-dropdown :id="comment.uri" variant="link" no-caret class="float-right">
  68. <template slot="button-content">
  69. <i class="fas fa-ellipsis-v text-muted"></i><span class="sr-only">Options</span>
  70. </template>
  71. <b-dropdown-item class="font-weight-bold" v-on:click="reply(comment)">Reply</b-dropdown-item>
  72. <b-dropdown-item class="font-weight-bold" :href="comment.url">Permalink</b-dropdown-item>
  73. <b-dropdown-item class="font-weight-bold" v-on:click="embed(comment)">Embed</b-dropdown-item>
  74. <b-dropdown-item class="font-weight-bold" :href="comment.account.url">Profile</b-dropdown-item>
  75. <b-dropdown-divider></b-dropdown-divider>
  76. <b-dropdown-item class="font-weight-bold" :href="'/i/report?type=post&id='+comment.id">Report</b-dropdown-item>
  77. </b-dropdown>
  78. </p>
  79. </div>
  80. </div>
  81. </div>
  82. </template>
  83. <script>
  84. export default {
  85. props: ['post-id', 'post-username'],
  86. data() {
  87. return {
  88. results: {},
  89. pagination: {},
  90. min_id: 0,
  91. max_id: 0,
  92. reply_to_profile_id: 0,
  93. }
  94. },
  95. mounted() {
  96. this.fetchData();
  97. },
  98. methods: {
  99. embed(e) {
  100. pixelfed.embed.build(e);
  101. },
  102. reply(e) {
  103. this.reply_to_profile_id = e.account.id;
  104. $('.comment-form input[name=comment]').val('@'+e.account.username+' ');
  105. $('.comment-form input[name=comment]').focus();
  106. },
  107. fetchData() {
  108. let url = '/api/v2/comments/'+this.postUsername+'/status/'+this.postId;
  109. axios.get(url)
  110. .then(response => {
  111. let self = this;
  112. this.results = response.data.data;
  113. this.pagination = response.data.meta.pagination;
  114. $('.lwrapper').addClass('d-none');
  115. $('.cwrapper').removeClass('d-none');
  116. }).catch(error => {
  117. $('.lds-ring').attr('style','width:100%').addClass('pt-4 font-weight-bold text-muted').text('An error occured, cannot fetch comments. Please try again later.');
  118. console.log(error);
  119. });
  120. },
  121. loadMore(e) {
  122. e.preventDefault();
  123. if(this.pagination.total_pages == 1 || this.pagination.current_page == this.pagination.total_pages) {
  124. $('.load-more-link').addClass('d-none');
  125. return;
  126. }
  127. $('.cwrapper').addClass('d-none');
  128. $('.lwrapper').removeClass('d-none');
  129. let next = this.pagination.links.next;
  130. axios.get(next)
  131. .then(response => {
  132. let self = this;
  133. let res = response.data.data;
  134. $('.lwrapper').addClass('d-none');
  135. for(let i=0; i < res.length; i++) {
  136. this.results.unshift(res[i]);
  137. }
  138. $('.cwrapper').removeClass('d-none');
  139. this.pagination = response.data.meta.pagination;
  140. });
  141. }
  142. }
  143. }
  144. </script>