logo

pleroma-fe

My custom branche(s) on git.pleroma.social/pleroma/pleroma-fe git clone https://anongit.hacktivis.me/git/pleroma-fe.git/

gallery.js (3463B)


  1. import { useMediaViewerStore } from 'src/stores/media_viewer'
  2. import Attachment from '../attachment/attachment.vue'
  3. import { sumBy, set } from 'lodash'
  4. const Gallery = {
  5. props: [
  6. 'attachments',
  7. 'compact',
  8. 'limitRows',
  9. 'descriptions',
  10. 'limit',
  11. 'nsfw',
  12. 'setMedia',
  13. 'size',
  14. 'editable',
  15. 'removeAttachment',
  16. 'shiftUpAttachment',
  17. 'shiftDnAttachment',
  18. 'editAttachment',
  19. 'grid'
  20. ],
  21. data () {
  22. return {
  23. sizes: {},
  24. hidingLong: true
  25. }
  26. },
  27. components: { Attachment },
  28. computed: {
  29. rows () {
  30. if (!this.attachments) {
  31. return []
  32. }
  33. const attachments = this.limit > 0
  34. ? this.attachments.slice(0, this.limit)
  35. : this.attachments
  36. if (this.size === 'hide') {
  37. return attachments.map(item => ({ minimal: true, items: [item] }))
  38. }
  39. const rows = this.grid
  40. ? [{ grid: true, items: attachments }]
  41. : attachments.reduce((acc, attachment, i) => {
  42. if (attachment.mimetype.includes('audio')) {
  43. return [...acc, { audio: true, items: [attachment] }, { items: [] }]
  44. }
  45. if (!(
  46. attachment.mimetype.includes('image') ||
  47. attachment.mimetype.includes('video') ||
  48. attachment.mimetype.includes('flash')
  49. )) {
  50. return [...acc, { minimal: true, items: [attachment] }, { items: [] }]
  51. }
  52. const maxPerRow = 3
  53. const attachmentsRemaining = this.attachments.length - i + 1
  54. const currentRow = acc[acc.length - 1].items
  55. currentRow.push(attachment)
  56. if (currentRow.length >= maxPerRow && attachmentsRemaining > maxPerRow) {
  57. return [...acc, { items: [] }]
  58. } else {
  59. return acc
  60. }
  61. }, [{ items: [] }]).filter(_ => _.items.length > 0)
  62. return rows
  63. },
  64. attachmentsDimensionalScore () {
  65. return this.rows.reduce((acc, row) => {
  66. let size = 0
  67. if (row.minimal) {
  68. size += 1 / 8
  69. } else if (row.audio) {
  70. size += 1 / 4
  71. } else {
  72. size += 1 / (row.items.length + 0.6)
  73. }
  74. return acc + size
  75. }, 0)
  76. },
  77. tooManyAttachments () {
  78. if (this.editable || this.size === 'small') {
  79. return false
  80. } else if (this.size === 'hide') {
  81. return this.attachments.length > 8
  82. } else {
  83. return this.attachmentsDimensionalScore > 1
  84. }
  85. }
  86. },
  87. methods: {
  88. onNaturalSizeLoad ({ id, width, height }) {
  89. set(this.sizes, id, { width, height })
  90. },
  91. rowStyle (row) {
  92. if (row.audio) {
  93. return { 'padding-bottom': '25%' } // fixed reduced height for audio
  94. } else if (!row.minimal && !row.grid) {
  95. return { 'padding-bottom': `${(100 / (row.items.length + 0.6))}%` }
  96. }
  97. },
  98. itemStyle (id, row) {
  99. const total = sumBy(row, item => this.getAspectRatio(item.id))
  100. return { flex: `${this.getAspectRatio(id) / total} 1 0%` }
  101. },
  102. getAspectRatio (id) {
  103. const size = this.sizes[id]
  104. return size ? size.width / size.height : 1
  105. },
  106. toggleHidingLong (event) {
  107. this.hidingLong = event
  108. },
  109. openGallery () {
  110. useMediaViewerStore().setMedia(this.attachments)
  111. useMediaViewerStore().setCurrentMedia(this.attachments[0])
  112. },
  113. onMedia () {
  114. useMediaViewerStore().setMedia(this.attachments)
  115. }
  116. }
  117. }
  118. export default Gallery