From e654fead23ebb457f81e8642c65e1f3e98ee0027 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Thu, 17 Jun 2021 16:29:46 +0300
Subject: refactored attachments and gallery. All attachments now are in
 gallery.

---
 src/components/gallery/gallery.vue | 175 ++++++++++++++++++++++++++-----------
 1 file changed, 124 insertions(+), 51 deletions(-)

(limited to 'src/components/gallery/gallery.vue')

diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index ca91c9c1..8e08e514 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -1,26 +1,74 @@
 <template>
   <div
+    class="Gallery"
     ref="galleryContainer"
-    style="width: 100%;"
+    :class="{ '-long': tooManyAttachments && hidingLong  }"
   >
+    <div class="gallery-rows">
+      <div
+        v-for="(row, index) in rows"
+        :key="index"
+        class="gallery-row"
+        :style="rowStyle(row)"
+        :class="{ '-audio': row.audio, '-minimal': row.minimal }"
+      >
+        <div class="gallery-row-inner">
+          <attachment
+            v-for="attachment in row.items"
+            class="gallery-item"
+            :key="attachment.id"
+            :set-media="setMedia"
+            :nsfw="nsfw"
+            :attachment="attachment"
+            :allow-play="false"
+            :size="size"
+            :natural-size-load="onNaturalSizeLoad.bind(null, attachment.id)"
+            :style="itemStyle(attachment.id, row.items)"
+          />
+        </div>
+      </div>
+    </div>
     <div
-      v-for="(row, index) in rows"
-      :key="index"
-      class="gallery-row"
-      :style="rowStyle(row.length)"
-      :class="{ 'contain-fit': useContainFit, 'cover-fit': !useContainFit }"
+      v-if="tooManyAttachments"
+      class="many-attachments"
     >
-      <div class="gallery-row-inner">
-        <attachment
-          v-for="attachment in row"
-          :key="attachment.id"
-          :set-media="setMedia"
-          :nsfw="nsfw"
-          :attachment="attachment"
-          :allow-play="false"
-          :natural-size-load="onNaturalSizeLoad.bind(null, attachment.id)"
-          :style="itemStyle(attachment.id, row)"
-        />
+      <div class="many-attachments-text">
+        {{ $t("status.many_attachments", { number: attachments.length })}}
+      </div>
+      <div class="many-attachments-buttons">
+        <span
+          v-if="!hidingLong"
+          class="many-attachments-button"
+        >
+          <button
+            class="button-unstyled -link"
+            @click="toggleHidingLong(true)"
+          >
+            {{ $t("status.collapse_attachments") }}
+          </button>
+        </span>
+        <span
+          v-if="hidingLong"
+          class="many-attachments-button"
+        >
+          <button
+            class="button-unstyled -link"
+            @click="toggleHidingLong(false)"
+          >
+            {{ $t("status.show_all_attachments") }}
+          </button>
+        </span>
+        <span
+          class="many-attachments-button"
+          v-if="hidingLong"
+        >
+          <button
+            class="button-unstyled -link"
+            @click="openGallery"
+          >
+            {{ $t("status.open_gallery") }}
+          </button>
+        </span>
       </div>
     </div>
   </div>
@@ -31,12 +79,64 @@
 <style lang="scss">
 @import '../../_variables.scss';
 
-.gallery-row {
-  position: relative;
-  height: 0;
-  width: 100%;
-  flex-grow: 1;
-  margin-top: 0.5em;
+.Gallery {
+  .gallery-rows {
+    display: flex;
+    flex-direction: column;
+  }
+
+  .gallery-row {
+    position: relative;
+    height: 0;
+    width: 100%;
+    flex-grow: 1;
+    margin-top: 0.5em;
+  }
+
+  &.-long {
+    .gallery-rows {
+      max-height: 25em;
+      overflow: hidden;
+      mask:
+        linear-gradient(to top, white, transparent) bottom/100% 70px no-repeat,
+        linear-gradient(to top, white, white);
+
+      /* Autoprefixed seem to ignore this one, and also syntax is different */
+      -webkit-mask-composite: xor;
+      mask-composite: exclude;
+    }
+  }
+
+  .many-attachments-text {
+    text-align: center;
+    line-height: 2;
+  }
+
+  .many-attachments-buttons {
+    display: flex;
+  }
+
+  .many-attachments-button {
+    display: flex;
+    flex: 1;
+    justify-content: center;
+    line-height: 2;
+
+    button {
+      padding: 0 2em;
+    }
+  }
+
+  .gallery-row {
+
+    &.-minimal {
+      height: auto;
+
+      .gallery-row-inner {
+        position: relative;
+      }
+    }
+  }
 
   .gallery-row-inner {
     position: absolute;
@@ -50,7 +150,7 @@
     align-content: stretch;
   }
 
-  .gallery-row-inner .attachment {
+  .gallery-item {
     margin: 0 0.5em 0 0;
     flex-grow: 1;
     height: 100%;
@@ -61,32 +161,5 @@
       margin: 0;
     }
   }
-
-  .image-attachment {
-    width: 100%;
-    height: 100%;
-  }
-
-  .video-container {
-    height: 100%;
-  }
-
-  &.contain-fit {
-    img,
-    video,
-    canvas {
-      object-fit: contain;
-      height: 100%;
-    }
-  }
-
-  &.cover-fit {
-    img,
-    video,
-    canvas {
-      object-fit: cover;
-    }
-  }
 }
-
 </style>
-- 
cgit v1.2.3-70-g09d2


From f15599e6e57477131ba5592e2874916ed1da06e2 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 18 Jun 2021 02:04:01 +0300
Subject: gallery in post status form!

---
 src/components/attachment/attachment.js            |  30 ++-
 src/components/attachment/attachment.vue           | 279 ++++++++++++---------
 src/components/gallery/gallery.js                  |  38 +--
 src/components/gallery/gallery.vue                 |   9 +-
 .../post_status_form/post_status_form.js           |   8 +-
 .../post_status_form/post_status_form.vue          |  57 ++---
 6 files changed, 228 insertions(+), 193 deletions(-)

(limited to 'src/components/gallery/gallery.vue')

diff --git a/src/components/attachment/attachment.js b/src/components/attachment/attachment.js
index 3ea96a7a..a80c5c2e 100644
--- a/src/components/attachment/attachment.js
+++ b/src/components/attachment/attachment.js
@@ -13,7 +13,9 @@ import {
   faPlayCircle,
   faTimes,
   faStop,
-  faSearchPlus
+  faSearchPlus,
+  faTrashAlt,
+  faPencilAlt
 } from '@fortawesome/free-solid-svg-icons'
 
 library.add(
@@ -24,19 +26,25 @@ library.add(
   faPlayCircle,
   faTimes,
   faStop,
-  faSearchPlus
+  faSearchPlus,
+  faTrashAlt,
+  faPencilAlt
 )
 
 const Attachment = {
   props: [
     'attachment',
+    'description',
+    'hideDescription',
     'nsfw',
     'size',
     'setMedia',
-    'naturalSizeLoad'
+    'remove',
+    'edit'
   ],
   data () {
     return {
+      localDescription: this.description || this.attachment.description,
       nsfwImage: this.$store.state.instance.nsfwCensorImage || nsfwImage,
       hideNsfwLocal: this.$store.getters.mergedConfig.hideNsfw,
       preloadImage: this.$store.getters.mergedConfig.preloadImage,
@@ -93,9 +101,6 @@ const Attachment = {
     isEmpty () {
       return (this.type === 'html' && !this.attachment.oembed) || this.type === 'unknown'
     },
-    isSmall () {
-      return this.size === 'small'
-    },
     useModal () {
       const modalTypes = this.size === 'hide' ? ['image', 'video', 'audio']
         : this.mergedConfig.playVideosInModal
@@ -105,6 +110,11 @@ const Attachment = {
     },
     ...mapGetters(['mergedConfig'])
   },
+  watch: {
+    localDescription (newVal) {
+      this.onEdit(newVal)
+    }
+  },
   methods: {
     linkClicked ({ target }) {
       if (target.tagName === 'A') {
@@ -121,6 +131,12 @@ const Attachment = {
       this.$emit('setMedia')
       this.$store.dispatch('setCurrentMedia', this.attachment)
     },
+    onEdit (event) {
+      console.log('ONEDIT', event)
+      this.edit && this.edit(this.attachment, event)
+    },
+    onRemove () {
+      this.remove && this.remove(this.attachment)
     },
     stopFlash () {
       this.$refs.flash.closePlayer()
@@ -154,7 +170,7 @@ const Attachment = {
     onImageLoad (image) {
       const width = image.naturalWidth
       const height = image.naturalHeight
-      this.naturalSizeLoad && this.naturalSizeLoad({ width, height })
+      this.$emit('naturalSizeLoad', { id: this.attachment.id, width, height })
     }
   }
 }
diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue
index fe9e9398..9b1e83a7 100644
--- a/src/components/attachment/attachment.vue
+++ b/src/components/attachment/attachment.vue
@@ -12,151 +12,180 @@
       :href="attachment.url"
       :alt="attachment.description"
       :title="attachment.description"
+      @click.prevent=""
     >
       <FAIcon :icon="placeholderIconClass" />
       <b>{{ nsfw ? "NSFW / " : "" }}</b>{{ placeholderName }}
     </a>
   </button>
   <div
-    v-else
-    v-show="!isEmpty"
     class="Attachment"
     :class="classNames"
+    v-else
   >
-    <a
-      v-if="hidden"
-      class="image-container"
-      :href="attachment.url"
-      :alt="attachment.description"
-      :title="attachment.description"
-      @click.prevent.stop="toggleHidden"
-    >
-      <img
-        :key="nsfwImage"
-        class="nsfw"
-        :src="nsfwImage"
-      >
-      <FAIcon
-        v-if="type === 'video'"
-        class="play-icon"
-        icon="play-circle"
-      />
-    </a>
     <div
-      class="attachment-buttons"
-      v-if="!hidden"
-      >
-      <button
-        v-if="type === 'flash' && flashLoaded"
-        class="button-unstyled attachment-button"
-        @click.prevent="stopFlash"
-      >
-        <FAIcon icon="stop" />
-      </button>
-      <button
-        v-if="!useModal"
-        class="button-unstyled attachment-button"
-        @click.prevent="openModalForce"
-      >
-        <FAIcon icon="search-plus" />
-      </button>
-      <button
-        v-if="nsfw && hideNsfwLocal"
-        class="button-unstyled attachment-button"
-        @click.prevent="toggleHidden"
-      >
-        <FAIcon icon="times" />
-      </button>
-    </div>
-
-    <a
-      v-if="type === 'image' && (!hidden || preloadImage)"
-      class="image-container"
-      :class="{'-hidden': hidden && preloadImage }"
-      :href="attachment.url"
-      target="_blank"
-      @click.stop.prevent="openModal"
+      class="attachment-wrapper"
+      v-show="!isEmpty"
     >
-      <StillImage
-        class="image"
-        :referrerpolicy="referrerpolicy"
-        :mimetype="attachment.mimetype"
-        :src="attachment.large_thumb_url || attachment.url"
-        :image-load-handler="onImageLoad"
+      <a
+        v-if="hidden"
+        class="image-container"
+        :href="attachment.url"
         :alt="attachment.description"
-      />
-    </a>
+        :title="attachment.description"
+        @click.prevent.stop="toggleHidden"
+      >
+        <img
+          :key="nsfwImage"
+          class="nsfw"
+          :src="nsfwImage"
+        >
+        <FAIcon
+          v-if="type === 'video'"
+          class="play-icon"
+          icon="play-circle"
+        />
+      </a>
+      <div
+        class="attachment-buttons"
+        v-if="!hidden"
+        >
+        <button
+          v-if="type === 'flash' && flashLoaded"
+          class="button-unstyled attachment-button"
+          @click.prevent="stopFlash"
+        >
+          <FAIcon icon="stop" />
+        </button>
+        <button
+          v-if="!useModal"
+          class="button-unstyled attachment-button"
+          @click.prevent="openModalForce"
+        >
+          <FAIcon icon="search-plus" />
+        </button>
+        <button
+          v-if="nsfw && hideNsfwLocal"
+          class="button-unstyled attachment-button"
+          @click.prevent="toggleHidden"
+        >
+          <FAIcon icon="times" />
+        </button>
+        <button
+          v-if="remove"
+          class="button-unstyled attachment-button"
+          @click.prevent="onRemove"
+        >
+          <FAIcon icon="trash-alt" />
+        </button>
+      </div>
 
-    <a
-      v-if="type === 'video' && !hidden"
-      class="video-container"
-      :href="attachment.url"
-      @click.stop.prevent="openModal"
-    >
-      <VideoAttachment
-        class="video"
-        :attachment="attachment"
-        :controls="!useModal"
-        @play="$emit('play')"
-        @pause="$emit('pause')"
-      />
-      <FAIcon
-        v-if="useModal"
-        class="play-icon"
-        icon="play-circle"
-      />
-    </a>
+      <a
+        v-if="type === 'image' && (!hidden || preloadImage)"
+        class="image-container"
+        :class="{'-hidden': hidden && preloadImage }"
+        :href="attachment.url"
+        target="_blank"
+        @click.stop.prevent="openModal"
+      >
+        <StillImage
+          class="image"
+          :referrerpolicy="referrerpolicy"
+          :mimetype="attachment.mimetype"
+          :src="attachment.large_thumb_url || attachment.url"
+          :image-load-handler="onImageLoad"
+          :alt="attachment.description"
+        />
+      </a>
 
-    <a
-      v-if="type === 'audio' && !hidden"
-      class="audio-container"
-      :href="attachment.url"
-      @click.stop.prevent="openModal"
-    >
-      <audio
-        v-if="type === 'audio'"
-        :src="attachment.url"
-        :alt="attachment.description"
-        :title="attachment.description"
-        controls
-        @play="$emit('play')"
-        @pause="$emit('pause')"
-      />
-    </a>
+      <a
+        v-if="type === 'video' && !hidden"
+        class="video-container"
+        :href="attachment.url"
+        @click.stop.prevent="openModal"
+      >
+        <VideoAttachment
+          class="video"
+          :attachment="attachment"
+          :controls="!useModal"
+          @play="$emit('play')"
+          @pause="$emit('pause')"
+        />
+        <FAIcon
+          v-if="useModal"
+          class="play-icon"
+          icon="play-circle"
+        />
+      </a>
+
+      <a
+        v-if="type === 'audio' && !hidden"
+        class="audio-container"
+        :href="attachment.url"
+        @click.stop.prevent="openModal"
+      >
+        <audio
+          v-if="type === 'audio'"
+          :src="attachment.url"
+          :alt="attachment.description"
+          :title="attachment.description"
+          controls
+          @play="$emit('play')"
+          @pause="$emit('pause')"
+        />
+      </a>
 
-    <div
-      v-if="type === 'html' && attachment.oembed"
-      class="oembed-container"
-      @click.prevent="linkClicked"
-    >
       <div
-        v-if="attachment.thumb_url"
-        class="image"
+        v-if="type === 'html' && attachment.oembed"
+        class="oembed-container"
+        @click.prevent="linkClicked"
       >
-        <img :src="attachment.thumb_url">
-      </div>
-      <div class="text">
-        <!-- eslint-disable vue/no-v-html -->
-        <h1><a :href="attachment.url">{{ attachment.oembed.title }}</a></h1>
-        <div v-html="attachment.oembed.oembedHTML" />
-        <!-- eslint-enable vue/no-v-html -->
+        <div
+          v-if="attachment.thumb_url"
+          class="image"
+        >
+          <img :src="attachment.thumb_url">
+        </div>
+        <div class="text">
+          <!-- eslint-disable vue/no-v-html -->
+          <h1><a :href="attachment.url">{{ attachment.oembed.title }}</a></h1>
+          <div v-html="attachment.oembed.oembedHTML" />
+          <!-- eslint-enable vue/no-v-html -->
+        </div>
       </div>
-    </div>
 
-    <a
-      v-if="type === 'flash' && !hidden"
-      class="flash-container"
-      :href="attachment.url"
-      @click.stop.prevent="openModal"
+      <a
+        v-if="type === 'flash' && !hidden"
+        class="flash-container"
+        :href="attachment.url"
+        @click.stop.prevent="openModal"
+      >
+        <Flash
+          class="flash"
+          ref="flash"
+          :src="attachment.large_thumb_url || attachment.url"
+          @playerOpened="setFlashLoaded(true)"
+          @playerClosed="setFlashLoaded(false)"
+        />
+      </a>
+    </div>
+    <div
+      v-if="size !== 'hide' && !hideDescription && (edit || localDescription)"
+      class="description-container"
+      :class="{ '-static': !edit }"
     >
-      <Flash
-        class="flash"
-        ref="flash"
-        :src="attachment.large_thumb_url || attachment.url"
-        @playerOpened="setFlashLoaded(true)"
-        @playerClosed="setFlashLoaded(false)"
-      />
-    </a>
+      <input
+        v-if="edit"
+        v-model="localDescription"
+        type="text"
+        class="description-field"
+        :placeholder="$t('post_status.media_description')"
+        @keydown.enter.prevent=""
+      >
+      <p v-else>
+        {{ localDescription }}
+      </p>
+    </div>
   </div>
 </template>
 
diff --git a/src/components/gallery/gallery.js b/src/components/gallery/gallery.js
index 134ea77e..cca67dbd 100644
--- a/src/components/gallery/gallery.js
+++ b/src/components/gallery/gallery.js
@@ -4,9 +4,15 @@ import { sumBy } from 'lodash'
 const Gallery = {
   props: [
     'attachments',
+    'limitRows',
+    'descriptions',
     'nsfw',
     'setMedia',
-    'size'
+    'size',
+    'editable',
+    'removeAttachment',
+    'editAttachment',
+    'maxPerRow'
   ],
   data () {
     return {
@@ -20,24 +26,19 @@ const Gallery = {
       if (!this.attachments) {
         return []
       }
-      console.log(this.size)
       if (this.size === 'hide') {
         return this.attachments.map(item => ({ minimal: true, items: [item] }))
       }
       const rows = this.attachments.reduce((acc, attachment, i) => {
+        if (this.size === 'small' && acc.length === 2) return acc
         if (attachment.mimetype.includes('audio')) {
           return [...acc, { audio: true, items: [attachment] }, { items: [] }]
         }
-        const maxPerRow = 3
-        const attachmentsRemaining = this.attachments.length - i - 1
+        const maxPerRow = this.maxPerRow || 3
+        const attachmentsRemaining = this.attachments.length - i + 1
         const currentRow = acc[acc.length - 1].items
-        if (
-          currentRow.length <= maxPerRow ||
-            attachmentsRemaining === 1
-        ) {
-          currentRow.push(attachment)
-        }
-        if (currentRow.length === maxPerRow && attachmentsRemaining > 1) {
+        currentRow.push(attachment)
+        if (currentRow.length >= maxPerRow && attachmentsRemaining > maxPerRow) {
           return [...acc, { items: [] }]
         } else {
           return acc
@@ -51,7 +52,9 @@ const Gallery = {
       }, 0)
     },
     tooManyAttachments () {
-      if (this.size === 'hide') {
+      if (this.editable || this.size === 'small') {
+        return false
+      } else if (this.size === 'hide') {
         return this.attachments.length > 8
       } else {
         return this.attachmentsDimensionalScore > 1
@@ -59,8 +62,8 @@ const Gallery = {
     }
   },
   methods: {
-    onNaturalSizeLoad (id, size) {
-      this.$set(this.sizes, id, size)
+    onNaturalSizeLoad ({ id, width, height }) {
+      this.$set(this.sizes, id, { width, height })
     },
     rowStyle (row) {
       if (row.audio) {
@@ -81,8 +84,11 @@ const Gallery = {
       this.hidingLong = event
     },
     openGallery () {
-      this.setMedia()
-      this.$store.dispatch('setCurrent', this.attachments[0])
+      this.$store.dispatch('setMedia', this.attachments)
+      this.$store.dispatch('setCurrentMedia', this.attachments[0])
+    },
+    onMedia () {
+      this.$store.dispatch('setMedia', this.attachments)
     }
   }
 }
diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index 8e08e514..cedf64d3 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -17,13 +17,18 @@
             v-for="attachment in row.items"
             class="gallery-item"
             :key="attachment.id"
-            :set-media="setMedia"
             :nsfw="nsfw"
             :attachment="attachment"
             :allow-play="false"
             :size="size"
-            :natural-size-load="onNaturalSizeLoad.bind(null, attachment.id)"
+            :editable="editable"
+            :remove="removeAttachment"
+            :edit="editAttachment"
+            :description="descriptions && descriptions[attachment.id]"
+            :hideDescription="tooManyAttachments && hidingLong"
             :style="itemStyle(attachment.id, row.items)"
+            @setMedia="onMedia"
+            @naturalSizeLoad="onNaturalSizeLoad"
           />
         </div>
       </div>
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index 5342894f..1a12db9c 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -4,6 +4,7 @@ import ScopeSelector from '../scope_selector/scope_selector.vue'
 import EmojiInput from '../emoji_input/emoji_input.vue'
 import PollForm from '../poll/poll_form.vue'
 import Attachment from '../attachment/attachment.vue'
+import Gallery from 'src/components/gallery/gallery.vue'
 import StatusContent from '../status_content/status_content.vue'
 import fileTypeService from '../../services/file_type/file_type.service.js'
 import { findOffset } from '../../services/offset_finder/offset_finder.service.js'
@@ -85,7 +86,8 @@ const PostStatusForm = {
     Checkbox,
     Select,
     Attachment,
-    StatusContent
+    StatusContent,
+    Gallery
   },
   mounted () {
     this.updateIdempotencyKey()
@@ -388,6 +390,10 @@ const PostStatusForm = {
       this.newStatus.files.splice(index, 1)
       this.$emit('resize')
     },
+    editAttachment (fileInfo, newText) {
+      console.log(fileInfo, newText)
+      this.newStatus.mediaDescriptions[fileInfo.id] = newText
+    },
     uploadFailed (errString, templateArgs) {
       templateArgs = templateArgs || {}
       this.error = this.$t('upload.error.base') + ' ' + this.$t('upload.error.' + errString, templateArgs)
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index fbda41d6..c6f84a4b 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -287,32 +287,21 @@
           @click="clearError"
         />
       </div>
-      <div class="attachments">
-        <div
-          v-for="file in newStatus.files"
-          :key="file.url"
-          class="media-upload-wrapper"
-        >
-          <button
-            class="button-unstyled hider"
-            @click="removeMediaFile(file)"
-          >
-            <FAIcon icon="times" />
-          </button>
-          <attachment
-            :attachment="file"
-            :set-media="() => $store.dispatch('setMedia', newStatus.files)"
-            size="small"
-            allow-play="false"
-          />
-          <input
-            v-model="newStatus.mediaDescriptions[file.id]"
-            type="text"
-            :placeholder="$t('post_status.media_description')"
-            @keydown.enter.prevent=""
-          >
-        </div>
-      </div>
+      <gallery
+        v-if="newStatus.files && newStatus.files.length > 0"
+        class="attachments"
+        :maxPerRow="1"
+        :nsfw="false"
+        :attachments="newStatus.files"
+        :descriptions="newStatus.mediaDescriptions"
+        :set-media="() => $store.dispatch('setMedia', newStatus.files)"
+        :editable="true"
+        :editAttachment="editAttachment"
+        :removeAttachment="removeMediaFile"
+        size="small"
+        @play="$emit('mediaplay', attachment.id)"
+        @pause="$emit('mediapause', attachment.id)"
+      />
       <div
         v-if="newStatus.files.length > 0 && !disableSensitivityCheckbox"
         class="upload_settings"
@@ -507,15 +496,6 @@
     flex-direction: column;
   }
 
-   .attachments .media-upload-wrapper {
-    position: relative;
-
-    .attachment {
-      margin: 0;
-      padding: 0;
-    }
-  }
-
   .btn {
     cursor: pointer;
   }
@@ -616,11 +596,4 @@
     border: 2px dashed var(--text, $fallback--text);
   }
 }
-
-// todo: unify with attachment.vue (otherwise the uploaded images are not minified unless a status with an attachment was displayed before)
-img.media-upload, .media-upload-container > video {
-  line-height: 0;
-  max-height: 200px;
-  max-width: 100%;
-}
 </style>
-- 
cgit v1.2.3-70-g09d2


From f35c090caaccf272c12358a2a02df71b9212d16c Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 18 Jun 2021 02:27:32 +0300
Subject: merged in compact notifs and improved upon it

---
 src/components/gallery/gallery.js                    | 10 +++++++---
 src/components/gallery/gallery.vue                   |  2 +-
 src/components/post_status_form/post_status_form.vue |  1 -
 src/components/status_body/status_body.scss          |  2 +-
 src/components/status_body/status_body.vue           |  5 ++++-
 src/components/status_content/status_content.vue     |  1 +
 6 files changed, 14 insertions(+), 7 deletions(-)

(limited to 'src/components/gallery/gallery.vue')

diff --git a/src/components/gallery/gallery.js b/src/components/gallery/gallery.js
index cca67dbd..ab13f698 100644
--- a/src/components/gallery/gallery.js
+++ b/src/components/gallery/gallery.js
@@ -6,6 +6,7 @@ const Gallery = {
     'attachments',
     'limitRows',
     'descriptions',
+    'limit',
     'nsfw',
     'setMedia',
     'size',
@@ -26,11 +27,14 @@ const Gallery = {
       if (!this.attachments) {
         return []
       }
+      console.log(this.limit)
+      const attachments = this.limit > 0
+        ? this.attachments.slice(0, this.limit)
+        : this.attachments
       if (this.size === 'hide') {
-        return this.attachments.map(item => ({ minimal: true, items: [item] }))
+        return attachments.map(item => ({ minimal: true, items: [item] }))
       }
-      const rows = this.attachments.reduce((acc, attachment, i) => {
-        if (this.size === 'small' && acc.length === 2) return acc
+      const rows = attachments.reduce((acc, attachment, i) => {
         if (attachment.mimetype.includes('audio')) {
           return [...acc, { audio: true, items: [attachment] }, { items: [] }]
         }
diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index cedf64d3..a1f1c26c 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -25,7 +25,7 @@
             :remove="removeAttachment"
             :edit="editAttachment"
             :description="descriptions && descriptions[attachment.id]"
-            :hideDescription="tooManyAttachments && hidingLong"
+            :hideDescription="size === 'small' || tooManyAttachments && hidingLong"
             :style="itemStyle(attachment.id, row.items)"
             @setMedia="onMedia"
             @naturalSizeLoad="onNaturalSizeLoad"
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index c6f84a4b..88ca4c9c 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -298,7 +298,6 @@
         :editable="true"
         :editAttachment="editAttachment"
         :removeAttachment="removeMediaFile"
-        size="small"
         @play="$emit('mediaplay', attachment.id)"
         @pause="$emit('mediapause', attachment.id)"
       />
diff --git a/src/components/status_body/status_body.scss b/src/components/status_body/status_body.scss
index 516ced9d..5be21171 100644
--- a/src/components/status_body/status_body.scss
+++ b/src/components/status_body/status_body.scss
@@ -151,7 +151,7 @@
 
     .attachments {
       margin-top: 0;
-      flex: 1 1 auto;
+      flex: 1 1 0;
       min-width: 5em;
       height: 100%;
     }
diff --git a/src/components/status_body/status_body.vue b/src/components/status_body/status_body.vue
index 2be46303..3eb13ce2 100644
--- a/src/components/status_body/status_body.vue
+++ b/src/components/status_body/status_body.vue
@@ -1,5 +1,8 @@
 <template>
-  <div class="StatusBody">
+<div
+  class="StatusBody"
+  :class="{ '-compact': compact }"
+  >
     <div class="body">
       <div
         v-if="status.summary_raw_html"
diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue
index c1533b19..90ce130d 100644
--- a/src/components/status_content/status_content.vue
+++ b/src/components/status_content/status_content.vue
@@ -20,6 +20,7 @@
         v-if="status.attachments.length !== 0"
         :nsfw="nsfwClickthrough"
         :attachments="status.attachments"
+        :limit="this.compact ? 1 : 0"
         :size="attachmentSize"
         @setMedia="onMedia"
         @play="$emit('mediaplay', attachment.id)"
-- 
cgit v1.2.3-70-g09d2


From bfe31e20eaddaa9435c98962c53c35f4184ed5fe Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 18 Jun 2021 14:12:50 +0300
Subject: better compact attachments

---
 src/components/attachment/attachment.js          | 17 +++++++++++++----
 src/components/gallery/gallery.vue               |  5 ++++-
 src/components/status_body/status_body.scss      |  6 +++---
 src/components/status_content/status_content.vue |  5 -----
 4 files changed, 20 insertions(+), 13 deletions(-)

(limited to 'src/components/gallery/gallery.vue')

diff --git a/src/components/attachment/attachment.js b/src/components/attachment/attachment.js
index a80c5c2e..84656ffa 100644
--- a/src/components/attachment/attachment.js
+++ b/src/components/attachment/attachment.js
@@ -68,6 +68,7 @@ const Attachment = {
           '-nsfw-placeholder': this.hidden
         },
         '-' + this.type,
+        '-' + this.size,
         `-${this.useContainFit ? 'contain' : 'cover'}-fit`
       ]
     },
@@ -102,10 +103,18 @@ const Attachment = {
       return (this.type === 'html' && !this.attachment.oembed) || this.type === 'unknown'
     },
     useModal () {
-      const modalTypes = this.size === 'hide' ? ['image', 'video', 'audio']
-        : this.mergedConfig.playVideosInModal
-          ? ['image', 'video']
-          : ['image']
+      let modalTypes = []
+      switch (this.size) {
+        case 'hide':
+        case 'small':
+          modalTypes = ['image', 'video', 'audio', 'flash']
+          break
+        default:
+          modalTypes = this.mergedConfig.playVideosInModal
+            ? ['image', 'video', 'flash']
+            : ['image']
+          break
+      }
       return modalTypes.includes(this.type)
     },
     ...mapGetters(['mergedConfig'])
diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index a1f1c26c..65175366 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -95,7 +95,10 @@
     height: 0;
     width: 100%;
     flex-grow: 1;
-    margin-top: 0.5em;
+
+    &:not(:first-child) {
+      margin-top: 0.5em;
+    }
   }
 
   &.-long {
diff --git a/src/components/status_body/status_body.scss b/src/components/status_body/status_body.scss
index 5be21171..f261108e 100644
--- a/src/components/status_body/status_body.scss
+++ b/src/components/status_body/status_body.scss
@@ -123,6 +123,7 @@
   }
 
   &.-compact {
+    align-items: top;
     flex-direction: row;
 
     --emoji-size: 16px;
@@ -140,9 +141,7 @@
       mask-size: auto 3.5em, auto auto;
       mask-position: 0 0, 0 0;
       mask-repeat: repeat-x, repeat;
-      mask-image:
-        linear-gradient(to top, white 0.5em, transparent 2.5em),
-        linear-gradient(to top, white, white);
+      mask-image: linear-gradient(to bottom, white 2em, transparent 3em);
 
       /* Autoprefixed seem to ignore this one, and also syntax is different */
       -webkit-mask-composite: xor;
@@ -154,6 +153,7 @@
       flex: 1 1 0;
       min-width: 5em;
       height: 100%;
+      margin-left: 0.5em;
     }
 
     .summary-wrapper {
diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue
index 90ce130d..573eadf5 100644
--- a/src/components/status_content/status_content.vue
+++ b/src/components/status_content/status_content.vue
@@ -51,10 +51,5 @@ $status-margin: 0.75em;
 .StatusContent {
   flex: 1;
   min-width: 0;
-  &.-compact {
-    flex {
-      display: flex;
-    }
-  }
 }
 </style>
-- 
cgit v1.2.3-70-g09d2


From 44b741e270fcd949d25340d34cabbe4361ac5a03 Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Fri, 18 Jun 2021 17:30:56 +0300
Subject: better attachments in uploading (grid layout)

---
 src/components/gallery/gallery.js                  | 49 +++++++++++-----------
 src/components/gallery/gallery.vue                 | 25 +++++++++--
 .../post_status_form/post_status_form.vue          | 19 +--------
 3 files changed, 47 insertions(+), 46 deletions(-)

(limited to 'src/components/gallery/gallery.vue')

diff --git a/src/components/gallery/gallery.js b/src/components/gallery/gallery.js
index 741f1de2..15436d61 100644
--- a/src/components/gallery/gallery.js
+++ b/src/components/gallery/gallery.js
@@ -13,7 +13,7 @@ const Gallery = {
     'editable',
     'removeAttachment',
     'editAttachment',
-    'maxPerRow'
+    'grid'
   ],
   data () {
     return {
@@ -27,34 +27,35 @@ const Gallery = {
       if (!this.attachments) {
         return []
       }
-      console.log(this.limit)
       const attachments = this.limit > 0
         ? this.attachments.slice(0, this.limit)
         : this.attachments
       if (this.size === 'hide') {
         return attachments.map(item => ({ minimal: true, items: [item] }))
       }
-      const rows = attachments.reduce((acc, attachment, i) => {
-        if (attachment.mimetype.includes('audio')) {
-          return [...acc, { audio: true, items: [attachment] }, { items: [] }]
-        }
-        if (!(
-          attachment.mimetype.includes('image') ||
-            attachment.mimetype.includes('video') ||
-            attachment.mimetype.includes('flash')
-        )) {
-          return [...acc, { minimal: true, items: [attachment] }, { items: [] }]
-        }
-        const maxPerRow = this.maxPerRow || 3
-        const attachmentsRemaining = this.attachments.length - i + 1
-        const currentRow = acc[acc.length - 1].items
-        currentRow.push(attachment)
-        if (currentRow.length >= maxPerRow && attachmentsRemaining > maxPerRow) {
-          return [...acc, { items: [] }]
-        } else {
-          return acc
-        }
-      }, [{ items: [] }]).filter(_ => _.items.length > 0)
+      const rows = this.grid
+        ? [{ grid: true, items: attachments }]
+        : attachments.reduce((acc, attachment, i) => {
+          if (attachment.mimetype.includes('audio')) {
+            return [...acc, { audio: true, items: [attachment] }, { items: [] }]
+          }
+          if (!(
+            attachment.mimetype.includes('image') ||
+              attachment.mimetype.includes('video') ||
+              attachment.mimetype.includes('flash')
+          )) {
+            return [...acc, { minimal: true, items: [attachment] }, { items: [] }]
+          }
+          const maxPerRow = 3
+          const attachmentsRemaining = this.attachments.length - i + 1
+          const currentRow = acc[acc.length - 1].items
+          currentRow.push(attachment)
+          if (currentRow.length >= maxPerRow && attachmentsRemaining > maxPerRow) {
+            return [...acc, { items: [] }]
+          } else {
+            return acc
+          }
+        }, [{ items: [] }]).filter(_ => _.items.length > 0)
       return rows
     },
     attachmentsDimensionalScore () {
@@ -87,7 +88,7 @@ const Gallery = {
     rowStyle (row) {
       if (row.audio) {
         return { 'padding-bottom': '25%' } // fixed reduced height for audio
-      } else if (!row.minimal) {
+      } else if (!row.minimal && !row.grid) {
         return { 'padding-bottom': `${(100 / (row.items.length + 0.6))}%` }
       }
     },
diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index 65175366..424a15f1 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -10,9 +10,12 @@
         :key="index"
         class="gallery-row"
         :style="rowStyle(row)"
-        :class="{ '-audio': row.audio, '-minimal': row.minimal }"
+        :class="{ '-audio': row.audio, '-minimal': row.minimal, '-grid': grid }"
       >
-        <div class="gallery-row-inner">
+        <div
+          class="gallery-row-inner"
+          :class="{ '-grid': grid }"
+        >
           <attachment
             v-for="attachment in row.items"
             class="gallery-item"
@@ -136,10 +139,9 @@
   }
 
   .gallery-row {
-
+    &.-grid,
     &.-minimal {
       height: auto;
-
       .gallery-row-inner {
         position: relative;
       }
@@ -156,6 +158,21 @@
     flex-direction: row;
     flex-wrap: nowrap;
     align-content: stretch;
+
+    &.-grid {
+      width: 100%;
+      height: auto;
+      position: relative;
+      display: grid;
+      grid-column-gap: 0.5em;
+      grid-row-gap: 0.5em;
+      grid-template-columns: repeat(auto-fit, minmax(15em, 1fr));
+
+      .gallery-item {
+        margin: 0;
+        height: 200px;
+      }
+    }
   }
 
   .gallery-item {
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index 5078ad5f..5ff191cf 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -290,7 +290,7 @@
       <gallery
         v-if="newStatus.files && newStatus.files.length > 0"
         class="attachments"
-        :maxPerRow="1"
+        :grid="true"
         :nsfw="false"
         :attachments="newStatus.files"
         :descriptions="newStatus.mediaDescriptions"
@@ -318,23 +318,6 @@
 <style lang="scss">
 @import '../../_variables.scss';
 
-.tribute-container {
-  ul {
-    padding: 0px;
-    li {
-      display: flex;
-      align-items: center;
-    }
-  }
-  img {
-    padding: 3px;
-    width: 16px;
-    height: 16px;
-    border-radius: $fallback--avatarAltRadius;
-    border-radius: var(--avatarAltRadius, $fallback--avatarAltRadius);
-  }
-}
-
 .post-status-form {
   position: relative;
 
-- 
cgit v1.2.3-70-g09d2


From 628b99d117240d3335d1730e66d7747c662a3acd Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 22 Jun 2021 20:37:08 +0300
Subject: don't stretch columns when uploading media

---
 src/components/gallery/gallery.vue | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

(limited to 'src/components/gallery/gallery.vue')

diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index 424a15f1..5a2de68d 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -166,7 +166,7 @@
       display: grid;
       grid-column-gap: 0.5em;
       grid-row-gap: 0.5em;
-      grid-template-columns: repeat(auto-fit, minmax(15em, 1fr));
+      grid-template-columns: repeat(auto-fill, minmax(15em, 1fr));
 
       .gallery-item {
         margin: 0;
-- 
cgit v1.2.3-70-g09d2


From b67db47c888dd45c49a49b82e7922c2bf40ed61c Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Tue, 22 Jun 2021 20:47:35 +0300
Subject: lint

---
 src/components/attachment/attachment.vue             | 16 ++++++++--------
 src/components/gallery/gallery.vue                   | 12 ++++++------
 src/components/post_status_form/post_status_form.vue |  4 ++--
 src/components/status_body/status_body.vue           |  6 +++---
 src/components/status_content/status_content.js      |  1 -
 src/components/status_content/status_content.vue     | 12 ++++++------
 6 files changed, 25 insertions(+), 26 deletions(-)

(limited to 'src/components/gallery/gallery.vue')

diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue
index e1e700c4..98d9c3ec 100644
--- a/src/components/attachment/attachment.vue
+++ b/src/components/attachment/attachment.vue
@@ -15,12 +15,12 @@
       @click.prevent=""
     >
       <FAIcon :icon="placeholderIconClass" />
-      <b>{{ nsfw ? "NSFW / " : "" }}</b>{{ this.edit ? '' : placeholderName }}
+      <b>{{ nsfw ? "NSFW / " : "" }}</b>{{ edit ? '' : placeholderName }}
     </a>
     <div
-      class="attachment-buttons"
       v-if="edit || remove"
-      >
+      class="attachment-buttons"
+    >
       <button
         v-if="remove"
         class="button-unstyled attachment-button"
@@ -48,13 +48,13 @@
     </div>
   </button>
   <div
+    v-else
     class="Attachment"
     :class="classNames"
-    v-else
   >
     <div
-      class="attachment-wrapper"
       v-show="!isEmpty"
+      class="attachment-wrapper"
     >
       <a
         v-if="hidden"
@@ -76,9 +76,9 @@
         />
       </a>
       <div
-        class="attachment-buttons"
         v-if="!hidden"
-        >
+        class="attachment-buttons"
+      >
         <button
           v-if="type === 'flash' && flashLoaded"
           class="button-unstyled attachment-button"
@@ -190,8 +190,8 @@
         @click.stop.prevent="openModal"
       >
         <Flash
-          class="flash"
           ref="flash"
+          class="flash"
           :src="attachment.large_thumb_url || attachment.url"
           @playerOpened="setFlashLoaded(true)"
           @playerClosed="setFlashLoaded(false)"
diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index 5a2de68d..18b94d58 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -1,8 +1,8 @@
 <template>
   <div
-    class="Gallery"
     ref="galleryContainer"
-    :class="{ '-long': tooManyAttachments && hidingLong  }"
+    class="Gallery"
+    :class="{ '-long': tooManyAttachments && hidingLong }"
   >
     <div class="gallery-rows">
       <div
@@ -18,8 +18,8 @@
         >
           <attachment
             v-for="attachment in row.items"
-            class="gallery-item"
             :key="attachment.id"
+            class="gallery-item"
             :nsfw="nsfw"
             :attachment="attachment"
             :allow-play="false"
@@ -28,7 +28,7 @@
             :remove="removeAttachment"
             :edit="editAttachment"
             :description="descriptions && descriptions[attachment.id]"
-            :hideDescription="size === 'small' || tooManyAttachments && hidingLong"
+            :hide-description="size === 'small' || tooManyAttachments && hidingLong"
             :style="itemStyle(attachment.id, row.items)"
             @setMedia="onMedia"
             @naturalSizeLoad="onNaturalSizeLoad"
@@ -41,7 +41,7 @@
       class="many-attachments"
     >
       <div class="many-attachments-text">
-        {{ $t("status.many_attachments", { number: attachments.length })}}
+        {{ $t("status.many_attachments", { number: attachments.length }) }}
       </div>
       <div class="many-attachments-buttons">
         <span
@@ -67,8 +67,8 @@
           </button>
         </span>
         <span
-          class="many-attachments-button"
           v-if="hidingLong"
+          class="many-attachments-button"
         >
           <button
             class="button-unstyled -link"
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index 5ff191cf..87e6d2ab 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -296,8 +296,8 @@
         :descriptions="newStatus.mediaDescriptions"
         :set-media="() => $store.dispatch('setMedia', newStatus.files)"
         :editable="true"
-        :editAttachment="editAttachment"
-        :removeAttachment="removeMediaFile"
+        :edit-attachment="editAttachment"
+        :remove-attachment="removeMediaFile"
         @play="$emit('mediaplay', attachment.id)"
         @pause="$emit('mediapause', attachment.id)"
       />
diff --git a/src/components/status_body/status_body.vue b/src/components/status_body/status_body.vue
index 91ab1797..1001508c 100644
--- a/src/components/status_body/status_body.vue
+++ b/src/components/status_body/status_body.vue
@@ -1,7 +1,7 @@
 <template>
-<div
-  class="StatusBody"
-  :class="{ '-compact': compact }"
+  <div
+    class="StatusBody"
+    :class="{ '-compact': compact }"
   >
     <div class="body">
       <div
diff --git a/src/components/status_content/status_content.js b/src/components/status_content/status_content.js
index 55f701d0..9059642e 100644
--- a/src/components/status_content/status_content.js
+++ b/src/components/status_content/status_content.js
@@ -3,7 +3,6 @@ import Poll from '../poll/poll.vue'
 import Gallery from '../gallery/gallery.vue'
 import StatusBody from 'src/components/status_body/status_body.vue'
 import LinkPreview from '../link-preview/link-preview.vue'
-import fileType from 'src/services/file_type/file_type.service'
 import { mapGetters, mapState } from 'vuex'
 import { library } from '@fortawesome/fontawesome-svg-core'
 import {
diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue
index 573eadf5..86b3c52a 100644
--- a/src/components/status_content/status_content.vue
+++ b/src/components/status_content/status_content.vue
@@ -1,8 +1,8 @@
 <template>
-<div
-  class="StatusContent"
-  :class="{ '-compact': compact }"
->
+  <div
+    class="StatusContent"
+    :class="{ '-compact': compact }"
+  >
     <slot name="header" />
     <StatusBody
       :status="status"
@@ -16,11 +16,11 @@
       </div>
 
       <gallery
-        class="attachments media-body"
         v-if="status.attachments.length !== 0"
+        class="attachments media-body"
         :nsfw="nsfwClickthrough"
         :attachments="status.attachments"
-        :limit="this.compact ? 1 : 0"
+        :limit="compact ? 1 : 0"
         :size="attachmentSize"
         @setMedia="onMedia"
         @play="$emit('mediaplay', attachment.id)"
-- 
cgit v1.2.3-70-g09d2


From 0507eb6550830f7b76910d51200675de0aa9b1de Mon Sep 17 00:00:00 2001
From: Henry Jameson <me@hjkos.com>
Date: Sun, 15 Aug 2021 21:04:49 +0300
Subject: ability to move attachments around when making a new post

---
 src/components/attachment/attachment.js            |  8 ++++++++
 src/components/attachment/attachment.vue           | 24 ++++++++++++++++++++--
 src/components/gallery/gallery.js                  |  2 ++
 src/components/gallery/gallery.vue                 | 10 +++++----
 .../post_status_form/post_status_form.js           | 13 +++++++++++-
 .../post_status_form/post_status_form.vue          |  2 ++
 src/i18n/en.json                                   |  7 +++++++
 7 files changed, 59 insertions(+), 7 deletions(-)

(limited to 'src/components/gallery/gallery.vue')

diff --git a/src/components/attachment/attachment.js b/src/components/attachment/attachment.js
index fea7c6f8..f9c8d981 100644
--- a/src/components/attachment/attachment.js
+++ b/src/components/attachment/attachment.js
@@ -42,6 +42,8 @@ const Attachment = {
     'size',
     'setMedia',
     'remove',
+    'shiftUp',
+    'shiftDn',
     'edit'
   ],
   data () {
@@ -154,6 +156,12 @@ const Attachment = {
     onRemove () {
       this.remove && this.remove(this.attachment)
     },
+    onShiftUp () {
+      this.shiftUp && this.shiftUp(this.attachment)
+    },
+    onShiftDn () {
+      this.shiftDn && this.shiftDn(this.attachment)
+    },
     stopFlash () {
       this.$refs.flash.closePlayer()
     },
diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue
index 82a72a8d..4abf63dd 100644
--- a/src/components/attachment/attachment.vue
+++ b/src/components/attachment/attachment.vue
@@ -30,7 +30,7 @@
       </button>
     </div>
     <div
-      v-if="size !== 'hide' && !hideDescription && (edit || localDescription)"
+      v-if="size !== 'hide' && !hideDescription && (edit || localDescription || showDescription)"
       class="description-container"
       :class="{ '-static': !edit }"
     >
@@ -83,6 +83,7 @@
           v-if="type === 'flash' && flashLoaded"
           class="button-unstyled attachment-button"
           @click.prevent="stopFlash"
+          :title="$t('status.attachment_stop_flash')"
         >
           <FAIcon icon="stop" />
         </button>
@@ -98,6 +99,7 @@
           v-if="!useModal"
           class="button-unstyled attachment-button"
           @click.prevent="openModalForce"
+          :title="$t('status.show_attachment_in_modal')"
         >
           <FAIcon icon="search-plus" />
         </button>
@@ -105,13 +107,31 @@
           v-if="nsfw && hideNsfwLocal"
           class="button-unstyled attachment-button"
           @click.prevent="toggleHidden"
+          :title="$t('status.hide_attachment')"
         >
           <FAIcon icon="times" />
         </button>
+        <button
+          v-if="shiftUp"
+          class="button-unstyled attachment-button"
+          @click.prevent="onShiftUp"
+          :title="$t('status.move_up')"
+        >
+          <FAIcon icon="chevron-left" />
+        </button>
+        <button
+          v-if="shiftDn"
+          class="button-unstyled attachment-button"
+          @click.prevent="onShiftDn"
+          :title="$t('status.move_down')"
+        >
+          <FAIcon icon="chevron-right" />
+        </button>
         <button
           v-if="remove"
           class="button-unstyled attachment-button"
           @click.prevent="onRemove"
+          :title="$t('status.remove_attachment')"
         >
           <FAIcon icon="trash-alt" />
         </button>
@@ -209,7 +229,7 @@
       </span>
     </div>
     <div
-      v-if="size !== 'hide' && !hideDescription && (edit || localDescription)"
+      v-if="size !== 'hide' && !hideDescription && (edit || (localDescription && showDescription))"
       class="description-container"
       :class="{ '-static': !edit }"
     >
diff --git a/src/components/gallery/gallery.js b/src/components/gallery/gallery.js
index 15436d61..094b3e57 100644
--- a/src/components/gallery/gallery.js
+++ b/src/components/gallery/gallery.js
@@ -12,6 +12,8 @@ const Gallery = {
     'size',
     'editable',
     'removeAttachment',
+    'shiftUpAttachment',
+    'shiftDnAttachment',
     'editAttachment',
     'grid'
   ],
diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index 18b94d58..f9cad8a9 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -6,8 +6,8 @@
   >
     <div class="gallery-rows">
       <div
-        v-for="(row, index) in rows"
-        :key="index"
+        v-for="(row, rowIndex) in rows"
+        :key="rowIndex"
         class="gallery-row"
         :style="rowStyle(row)"
         :class="{ '-audio': row.audio, '-minimal': row.minimal, '-grid': grid }"
@@ -16,8 +16,8 @@
           class="gallery-row-inner"
           :class="{ '-grid': grid }"
         >
-          <attachment
-            v-for="attachment in row.items"
+          <Attachment
+            v-for="(attachment, attachmentIndex) in row.items"
             :key="attachment.id"
             class="gallery-item"
             :nsfw="nsfw"
@@ -26,6 +26,8 @@
             :size="size"
             :editable="editable"
             :remove="removeAttachment"
+            :shiftUp="!(attachmentIndex === 0 && rowIndex === 0) && shiftUpAttachment"
+            :shiftDn="!(attachmentIndex === row.items.length - 1 && rowIndex === rows.length - 1) && shiftDnAttachment"
             :edit="editAttachment"
             :description="descriptions && descriptions[attachment.id]"
             :hide-description="size === 'small' || tooManyAttachments && hidingLong"
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index 1a12db9c..fe07309f 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -391,9 +391,20 @@ const PostStatusForm = {
       this.$emit('resize')
     },
     editAttachment (fileInfo, newText) {
-      console.log(fileInfo, newText)
       this.newStatus.mediaDescriptions[fileInfo.id] = newText
     },
+    shiftUpMediaFile (fileInfo) {
+      const { files } = this.newStatus
+      const index = this.newStatus.files.indexOf(fileInfo)
+      files.splice(index, 1)
+      files.splice(index - 1, 0, fileInfo)
+    },
+    shiftDnMediaFile (fileInfo) {
+      const { files } = this.newStatus
+      const index = this.newStatus.files.indexOf(fileInfo)
+      files.splice(index, 1)
+      files.splice(index + 1, 0, fileInfo)
+    },
     uploadFailed (errString, templateArgs) {
       templateArgs = templateArgs || {}
       this.error = this.$t('upload.error.base') + ' ' + this.$t('upload.error.' + errString, templateArgs)
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index 87e6d2ab..2e0980a2 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -298,6 +298,8 @@
         :editable="true"
         :edit-attachment="editAttachment"
         :remove-attachment="removeMediaFile"
+        :shift-up-attachment="newStatus.files.length > 1 && shiftUpMediaFile"
+        :shift-dn-attachment="newStatus.files.length > 1 && shiftDnMediaFile"
         @play="$emit('mediaplay', attachment.id)"
         @pause="$emit('mediapause', attachment.id)"
       />
diff --git a/src/i18n/en.json b/src/i18n/en.json
index a4f24c64..0ccd0da7 100644
--- a/src/i18n/en.json
+++ b/src/i18n/en.json
@@ -721,6 +721,13 @@
     "many_attachments": "Post has {number} attachment(s)",
     "collapse_attachments": "Collapse attachments",
     "show_all_attachments": "Show all attachments",
+    "show_attachment_in_modal": "Show in media modal",
+    "show_attachment_description": "Preview description (open attachment for full description)",
+    "hide_attachment": "Hide attachment",
+    "remove_attachment": "Remove attachment",
+    "attachment_stop_flash": "Stop Flash player",
+    "move_up": "Shift attachment left",
+    "move_down": "Shift attachment right",
     "open_gallery": "Open gallery"
   },
   "user_card": {
-- 
cgit v1.2.3-70-g09d2


From 7a8c975f616f745b57a8426e40d7573d08b8416d Mon Sep 17 00:00:00 2001
From: Tusooa Zhu <tusooa@kazv.moe>
Date: Sun, 6 Mar 2022 14:22:59 -0500
Subject: Lint

---
 src/components/attachment/attachment.vue | 19 +++++++++++--------
 src/components/gallery/gallery.vue       |  4 ++--
 2 files changed, 13 insertions(+), 10 deletions(-)

(limited to 'src/components/gallery/gallery.vue')

diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue
index d1d43ac3..2a89886d 100644
--- a/src/components/attachment/attachment.vue
+++ b/src/components/attachment/attachment.vue
@@ -82,56 +82,56 @@
         <button
           v-if="type === 'flash' && flashLoaded"
           class="button-unstyled attachment-button"
-          @click.prevent="stopFlash"
           :title="$t('status.attachment_stop_flash')"
+          @click.prevent="stopFlash"
         >
           <FAIcon icon="stop" />
         </button>
         <button
           v-if="attachment.description && size !== 'small' && !edit && type !== 'unknown'"
           class="button-unstyled attachment-button"
-          @click.prevent="toggleDescription"
           :title="$t('status.show_attachment_description')"
+          @click.prevent="toggleDescription"
         >
           <FAIcon icon="align-right" />
         </button>
         <button
           v-if="!useModal && type !== 'unknown'"
           class="button-unstyled attachment-button"
-          @click.prevent="openModalForce"
           :title="$t('status.show_attachment_in_modal')"
+          @click.prevent="openModalForce"
         >
           <FAIcon icon="search-plus" />
         </button>
         <button
           v-if="nsfw && hideNsfwLocal"
           class="button-unstyled attachment-button"
-          @click.prevent="toggleHidden"
           :title="$t('status.hide_attachment')"
+          @click.prevent="toggleHidden"
         >
           <FAIcon icon="times" />
         </button>
         <button
           v-if="shiftUp"
           class="button-unstyled attachment-button"
-          @click.prevent="onShiftUp"
           :title="$t('status.move_up')"
+          @click.prevent="onShiftUp"
         >
           <FAIcon icon="chevron-left" />
         </button>
         <button
           v-if="shiftDn"
           class="button-unstyled attachment-button"
-          @click.prevent="onShiftDn"
           :title="$t('status.move_down')"
+          @click.prevent="onShiftDn"
         >
           <FAIcon icon="chevron-right" />
         </button>
         <button
           v-if="remove"
           class="button-unstyled attachment-button"
-          @click.prevent="onRemove"
           :title="$t('status.remove_attachment')"
+          @click.prevent="onRemove"
         >
           <FAIcon icon="trash-alt" />
         </button>
@@ -161,7 +161,10 @@
         :href="attachment.url"
         target="_blank"
       >
-        <FAIcon size="5x" :icon="placeholderIconClass" />
+        <FAIcon
+          size="5x"
+          :icon="placeholderIconClass"
+        />
         <p>
           {{ localDescription }}
         </p>
diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index f9cad8a9..f2e1b5ce 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -26,8 +26,8 @@
             :size="size"
             :editable="editable"
             :remove="removeAttachment"
-            :shiftUp="!(attachmentIndex === 0 && rowIndex === 0) && shiftUpAttachment"
-            :shiftDn="!(attachmentIndex === row.items.length - 1 && rowIndex === rows.length - 1) && shiftDnAttachment"
+            :shift-up="!(attachmentIndex === 0 && rowIndex === 0) && shiftUpAttachment"
+            :shift-dn="!(attachmentIndex === row.items.length - 1 && rowIndex === rows.length - 1) && shiftDnAttachment"
             :edit="editAttachment"
             :description="descriptions && descriptions[attachment.id]"
             :hide-description="size === 'small' || tooManyAttachments && hidingLong"
-- 
cgit v1.2.3-70-g09d2

