MediaContainer.vue 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243
  1. <template>
  2. <div class="feed-media-container bg-black">
  3. <div class="text-muted" style="max-height: 400px;">
  4. <div>
  5. <div v-if="post.pf_type === 'photo'">
  6. <div v-if="post.sensitive == true" class="content-label-wrapper">
  7. <div class="text-light content-label">
  8. <p class="text-center">
  9. <i class="far fa-eye-slash fa-2x"></i>
  10. </p>
  11. <p class="h4 font-weight-bold text-center">
  12. {{ $t('common.sensitiveContent') }}
  13. </p>
  14. <p class="text-center py-2 content-label-text">
  15. {{ post.spoiler_text ? post.spoiler_text : $t('common.sensitiveContentWarning') }}
  16. </p>
  17. <p class="mb-0">
  18. <button class="btn btn-outline-light btn-block btn-sm font-weight-bold" @click="toggleContentWarning()">See Post</button>
  19. </p>
  20. </div>
  21. <blur-hash-image
  22. width="32"
  23. height="32"
  24. :punch="1"
  25. class="blurhash-wrapper"
  26. :hash="post.media_attachments[0].blurhash"
  27. />
  28. </div>
  29. <div v-else class="content-label-wrapper">
  30. <blur-hash-image
  31. :key="key"
  32. width="32"
  33. height="32"
  34. :punch="1"
  35. :hash="post.media_attachments[0].blurhash"
  36. :src="post.media_attachments[0].url"
  37. class="blurhash-wrapper"
  38. />
  39. <p v-if="!post.sensitive && sensitive"
  40. @click="post.sensitive = true"
  41. style="
  42. margin-top: 0;
  43. padding: 10px;
  44. color: #000;
  45. font-size: 10px;
  46. text-align: right;
  47. position: absolute;
  48. top: 0;
  49. right: 0;
  50. border-radius: 11px;
  51. cursor: pointer;
  52. background: rgba(255, 255, 255,.5);
  53. ">
  54. <i class="fas fa-eye-slash fa-lg"></i>
  55. </p>
  56. </div>
  57. </div>
  58. <!-- <div v-else-if="post.pf_type === 'photo:album'">
  59. <img :src="media[mediaIndex].url" style="width: 100%;height: 500px;object-fit: contain;">
  60. <div class="d-flex mt-3 justify-content-center">
  61. <div
  62. v-for="(thumb, index) in media"
  63. class="mr-2 border rounded p-1"
  64. :class="[ index === mediaIndex ? 'border-light' : 'border-dark' ]"
  65. @click="mediaIndex = index">
  66. <img :src="thumb.preview_url" width="60" height="40" style="object-fit:cover;">
  67. </div>
  68. </div>
  69. </div> -->
  70. <!-- <photo-album-presenter :status="post" v-on:togglecw="post.sensitive = false"/> -->
  71. <!-- <video-presenter v-else-if="post.pf_type === 'video'" :status="post" v-on:togglecw="post.sensitive = false" /> -->
  72. </div>
  73. </div>
  74. </div>
  75. </template>
  76. <script type="text/javascript">
  77. export default {
  78. props: {
  79. post: {
  80. type: Object
  81. },
  82. profile: {
  83. type: Object
  84. },
  85. user: {
  86. type: Object
  87. },
  88. media: {
  89. type: Array
  90. },
  91. showArrows: {
  92. type: Boolean,
  93. default: true
  94. }
  95. },
  96. data() {
  97. return {
  98. loading: false,
  99. shortcuts: undefined,
  100. sensitive: false,
  101. mediaIndex: 0
  102. }
  103. },
  104. mounted() {
  105. this.initShortcuts();
  106. },
  107. beforeDestroy() {
  108. document.removeEventListener('keyup', this.shortcuts);
  109. },
  110. methods: {
  111. navPrev() {
  112. // event.currentTarget.blur();
  113. if(this.mediaIndex == 0) {
  114. this.loading = true;
  115. axios.get('/api/v1/accounts/' + this.profile.id + '/statuses', {
  116. params: {
  117. limit: 1,
  118. max_id: this.post.id
  119. }
  120. }).then(res => {
  121. if(!res.data.length) {
  122. this.mediaIndex = this.media.length - 1;
  123. this.loading = false;
  124. return;
  125. }
  126. this.$emit('navigate', res.data[0]);
  127. this.mediaIndex = 0;
  128. // this.post = res.data[0];
  129. // this.media = this.post.media_attachments;
  130. // this.fetchState(this.post.account.username, this.post.id);
  131. // this.loading = false;
  132. let url = window.location.origin + `/@${this.post.account.username}/post/${this.post.id}`;
  133. history.pushState(null, null, url);
  134. }).catch(err => {
  135. this.mediaIndex = this.media.length - 1;
  136. this.loading = false;
  137. });
  138. return;
  139. }
  140. this.mediaIndex--;
  141. },
  142. navNext() {
  143. // event.currentTarget.blur();
  144. if(this.mediaIndex == this.media.length - 1) {
  145. this.loading = true;
  146. axios.get('/api/v1/accounts/' + this.profile.id + '/statuses', {
  147. params: {
  148. limit: 1,
  149. min_id: this.post.id
  150. }
  151. }).then(res => {
  152. if(!res.data.length) {
  153. this.mediaIndex = 0;
  154. this.loading = false;
  155. return;
  156. }
  157. this.$emit('navigate', res.data[0]);
  158. this.mediaIndex = 0;
  159. // this.post = res.data[0];
  160. // this.media = this.post.media_attachments;
  161. // this.fetchState(this.post.account.username, this.post.id);
  162. // this.loading = false;
  163. let url = window.location.origin + `/@${this.post.account.username}/post/${this.post.id}`;
  164. history.pushState(null, null, url);
  165. }).catch(err => {
  166. this.mediaIndex = 0;
  167. this.loading = false;
  168. });
  169. return;
  170. }
  171. this.mediaIndex++;
  172. },
  173. initShortcuts() {
  174. this.shortcuts = document.addEventListener('keyup', event => {
  175. if (event.key === 'ArrowLeft') {
  176. this.navPrev();
  177. }
  178. if (event.key === 'ArrowRight') {
  179. this.navNext();
  180. }
  181. });
  182. },
  183. }
  184. }
  185. </script>
  186. <style lang="scss">
  187. .feed-media-container {
  188. .blurhash-wrapper {
  189. img {
  190. border-radius:15px;
  191. max-height: 400px;
  192. object-fit: contain;
  193. background-color: #000;
  194. }
  195. canvas {
  196. border-radius: 15px;
  197. max-height: 400px;
  198. }
  199. }
  200. .content-label-wrapper {
  201. position: relative;
  202. }
  203. .content-label {
  204. margin: 0;
  205. position: absolute;
  206. top:0;
  207. left:0;
  208. display: flex;
  209. flex-direction: column;
  210. align-items: center;
  211. justify-content: center;
  212. width: 100%;
  213. height: 400px;
  214. z-index: 2;
  215. border-radius: 15px;
  216. background: rgba(0, 0, 0, 0.2)
  217. }
  218. }
  219. </style>