logo

pleroma-fe

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

gallery.js (3407B)


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