aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
authorShpuld Shpludson <shp@cock.li>2020-07-07 12:14:58 +0000
committerShpuld Shpludson <shp@cock.li>2020-07-07 12:14:58 +0000
commitec26ff04ce541c3ba5a7f89d57cd04f74e79cfcc (patch)
tree7b85ca1b8001d4aedb4a49291c1c5425f30853b0 /src/components
parentbbb977a04475a445fc0588af86b3c5eb33ec0577 (diff)
parent0fe5d4cf1074fe6c4a811728de187fccadf1cac3 (diff)
Merge branch 'xenofem/pleroma-fe-rebased-image-description-authoring' into 'develop'
media description authoring v3 See merge request pleroma/pleroma-fe!1161
Diffstat (limited to 'src/components')
-rw-r--r--src/components/attachment/attachment.js32
-rw-r--r--src/components/attachment/attachment.vue31
-rw-r--r--src/components/gallery/gallery.vue4
-rw-r--r--src/components/media_modal/media_modal.vue10
-rw-r--r--src/components/post_status_form/post_status_form.js73
-rw-r--r--src/components/post_status_form/post_status_form.vue68
-rw-r--r--src/components/status_content/status_content.js11
-rw-r--r--src/components/status_content/status_content.vue12
-rw-r--r--src/components/still-image/still-image.js3
-rw-r--r--src/components/still-image/still-image.vue2
-rw-r--r--src/components/video_attachment/video_attachment.vue2
11 files changed, 146 insertions, 102 deletions
diff --git a/src/components/attachment/attachment.js b/src/components/attachment/attachment.js
index b832e10f..cb31020d 100644
--- a/src/components/attachment/attachment.js
+++ b/src/components/attachment/attachment.js
@@ -8,7 +8,6 @@ const Attachment = {
props: [
'attachment',
'nsfw',
- 'statusId',
'size',
'allowPlay',
'setMedia',
@@ -30,9 +29,21 @@ const Attachment = {
VideoAttachment
},
computed: {
- usePlaceHolder () {
+ usePlaceholder () {
return this.size === 'hide' || this.type === 'unknown'
},
+ placeholderName () {
+ if (this.attachment.description === '' || !this.attachment.description) {
+ return this.type.toUpperCase()
+ }
+ return this.attachment.description
+ },
+ placeholderIconClass () {
+ if (this.type === 'image') return 'icon-picture'
+ if (this.type === 'video') return 'icon-video'
+ if (this.type === 'audio') return 'icon-music'
+ return 'icon-doc'
+ },
referrerpolicy () {
return this.$store.state.instance.mediaProxyAvailable ? '' : 'no-referrer'
},
@@ -49,7 +60,15 @@ const Attachment = {
return this.size === 'small'
},
fullwidth () {
- return this.type === 'html' || this.type === 'audio'
+ if (this.size === 'hide') return false
+ return this.type === 'html' || this.type === 'audio' || this.type === 'unknown'
+ },
+ useModal () {
+ const modalTypes = this.size === 'hide' ? ['image', 'video', 'audio']
+ : this.mergedConfig.playVideosInModal
+ ? ['image', 'video']
+ : ['image']
+ return modalTypes.includes(this.type)
},
...mapGetters(['mergedConfig'])
},
@@ -60,12 +79,7 @@ const Attachment = {
}
},
openModal (event) {
- const modalTypes = this.mergedConfig.playVideosInModal
- ? ['image', 'video']
- : ['image']
- if (fileTypeService.fileMatchesSomeType(modalTypes, this.attachment) ||
- this.usePlaceHolder
- ) {
+ if (this.useModal) {
event.stopPropagation()
event.preventDefault()
this.setMedia()
diff --git a/src/components/attachment/attachment.vue b/src/components/attachment/attachment.vue
index a7e217c1..be7377e9 100644
--- a/src/components/attachment/attachment.vue
+++ b/src/components/attachment/attachment.vue
@@ -1,6 +1,7 @@
<template>
<div
- v-if="usePlaceHolder"
+ v-if="usePlaceholder"
+ :class="{ 'fullwidth': fullwidth }"
@click="openModal"
>
<a
@@ -8,8 +9,11 @@
class="placeholder"
target="_blank"
:href="attachment.url"
+ :alt="attachment.description"
+ :title="attachment.description"
>
- [{{ nsfw ? "NSFW/" : "" }}{{ type.toUpperCase() }}]
+ <span :class="placeholderIconClass" />
+ <b>{{ nsfw ? "NSFW / " : "" }}</b>{{ placeholderName }}
</a>
</div>
<div
@@ -22,6 +26,8 @@
v-if="hidden"
class="image-attachment"
:href="attachment.url"
+ :alt="attachment.description"
+ :title="attachment.description"
@click.prevent="toggleHidden"
>
<img
@@ -51,7 +57,6 @@
:class="{'hidden': hidden && preloadImage }"
:href="attachment.url"
target="_blank"
- :title="attachment.description"
@click="openModal"
>
<StillImage
@@ -59,6 +64,7 @@
:mimetype="attachment.mimetype"
:src="attachment.large_thumb_url || attachment.url"
:image-load-handler="onImageLoad"
+ :alt="attachment.description"
/>
</a>
@@ -83,6 +89,8 @@
<audio
v-if="type === 'audio'"
:src="attachment.url"
+ :alt="attachment.description"
+ :title="attachment.description"
controls
/>
@@ -116,22 +124,19 @@
display: flex;
flex-wrap: wrap;
- .attachment.media-upload-container {
- flex: 0 0 auto;
- max-height: 200px;
+ .non-gallery {
max-width: 100%;
- display: flex;
- align-items: center;
- video {
- max-width: 100%;
- }
}
.placeholder {
- margin-right: 8px;
- margin-bottom: 4px;
+ display: inline-block;
+ padding: 0.3em 1em 0.3em 0;
color: $fallback--link;
color: var(--postLink, $fallback--link);
+ overflow: hidden;
+ white-space: nowrap;
+ text-overflow: ellipsis;
+ max-width: 100%;
}
.nsfw-placeholder {
diff --git a/src/components/gallery/gallery.vue b/src/components/gallery/gallery.vue
index 1ffa7b3c..ca91c9c1 100644
--- a/src/components/gallery/gallery.vue
+++ b/src/components/gallery/gallery.vue
@@ -50,9 +50,7 @@
align-content: stretch;
}
- // FIXME: specificity problem with this and .attachments.attachment
- // we shouldn't have the need for .image here
- .attachment.image {
+ .gallery-row-inner .attachment {
margin: 0 0.5em 0 0;
flex-grow: 1;
height: 100%;
diff --git a/src/components/media_modal/media_modal.vue b/src/components/media_modal/media_modal.vue
index 80d2a8b9..46931667 100644
--- a/src/components/media_modal/media_modal.vue
+++ b/src/components/media_modal/media_modal.vue
@@ -8,6 +8,8 @@
v-if="type === 'image'"
class="modal-image"
:src="currentMedia.url"
+ :alt="currentMedia.description"
+ :title="currentMedia.description"
@touchstart.stop="mediaTouchStart"
@touchmove.stop="mediaTouchMove"
@click="hide"
@@ -18,6 +20,14 @@
:attachment="currentMedia"
:controls="true"
/>
+ <audio
+ v-if="type === 'audio'"
+ class="modal-image"
+ :src="currentMedia.url"
+ :alt="currentMedia.description"
+ :title="currentMedia.description"
+ controls
+ />
<button
v-if="canNavigate"
:title="$t('media_modal.previous')"
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index 62e0d7e4..18f02eba 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -3,6 +3,7 @@ import MediaUpload from '../media_upload/media_upload.vue'
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 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'
@@ -40,6 +41,7 @@ const PostStatusForm = {
PollForm,
ScopeSelector,
Checkbox,
+ Attachment,
StatusContent
},
mounted () {
@@ -80,6 +82,7 @@ const PostStatusForm = {
nsfw: false,
files: [],
poll: {},
+ mediaDescriptions: {},
visibility: scope,
contentType
},
@@ -184,7 +187,7 @@ const PostStatusForm = {
}
},
methods: {
- postStatus (newStatus) {
+ async postStatus (newStatus) {
if (this.posting) { return }
if (this.submitDisabled) { return }
if (this.emptyStatus) {
@@ -199,7 +202,16 @@ const PostStatusForm = {
}
this.posting = true
- statusPoster.postStatus({
+
+ try {
+ await this.setAllMediaDescriptions()
+ } catch (e) {
+ this.error = this.$t('post_status.media_description_error')
+ this.posting = false
+ return
+ }
+
+ const data = await statusPoster.postStatus({
status: newStatus.status,
spoilerText: newStatus.spoilerText || null,
visibility: newStatus.visibility,
@@ -209,30 +221,32 @@ const PostStatusForm = {
inReplyToStatusId: this.replyTo,
contentType: newStatus.contentType,
poll
- }).then((data) => {
- if (!data.error) {
- this.newStatus = {
- status: '',
- spoilerText: '',
- files: [],
- visibility: newStatus.visibility,
- contentType: newStatus.contentType,
- poll: {}
- }
- this.pollFormVisible = false
- this.$refs.mediaUpload.clearFile()
- this.clearPollForm()
- this.$emit('posted')
- let el = this.$el.querySelector('textarea')
- el.style.height = 'auto'
- el.style.height = undefined
- this.error = null
- if (this.preview) this.previewStatus()
- } else {
- this.error = data.error
- }
- this.posting = false
})
+
+ if (!data.error) {
+ this.newStatus = {
+ status: '',
+ spoilerText: '',
+ files: [],
+ visibility: newStatus.visibility,
+ contentType: newStatus.contentType,
+ poll: {},
+ mediaDescriptions: {}
+ }
+ this.pollFormVisible = false
+ this.$refs.mediaUpload.clearFile()
+ this.clearPollForm()
+ this.$emit('posted')
+ let el = this.$el.querySelector('textarea')
+ el.style.height = 'auto'
+ el.style.height = undefined
+ this.error = null
+ if (this.preview) this.previewStatus()
+ } else {
+ this.error = data.error
+ }
+
+ this.posting = false
},
previewStatus () {
if (this.emptyStatus && this.newStatus.spoilerText.trim() === '') {
@@ -457,6 +471,15 @@ const PostStatusForm = {
},
dismissScopeNotice () {
this.$store.dispatch('setOption', { name: 'hideScopeNotice', value: true })
+ },
+ setMediaDescription (id) {
+ const description = this.newStatus.mediaDescriptions[id]
+ if (!description || description.trim() === '') return
+ return statusPoster.setMediaDescription({ store: this.$store, id, description })
+ },
+ setAllMediaDescriptions () {
+ const ids = this.newStatus.files.map(file => file.id)
+ return Promise.all(ids.map(id => this.setMediaDescription(id)))
}
}
}
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index 60dc4a21..626584ed 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -282,27 +282,18 @@
class="fa button-icon icon-cancel"
@click="removeMediaFile(file)"
/>
- <div class="media-upload-container attachment">
- <img
- v-if="type(file) === 'image'"
- class="thumbnail media-upload"
- :src="file.url"
- >
- <video
- v-if="type(file) === 'video'"
- :src="file.url"
- controls
- />
- <audio
- v-if="type(file) === 'audio'"
- :src="file.url"
- controls
- />
- <a
- v-if="type(file) === 'unknown'"
- :href="file.url"
- >{{ file.url }}</a>
- </div>
+ <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>
<div
@@ -458,11 +449,9 @@
}
.media-upload-wrapper {
- flex: 0 0 auto;
- max-width: 100%;
- min-width: 50px;
margin-right: .2em;
margin-bottom: .5em;
+ width: 18em;
.icon-cancel {
display: inline-block;
@@ -476,6 +465,20 @@
border-bottom-left-radius: 0;
border-bottom-right-radius: 0;
}
+
+ img, video {
+ object-fit: contain;
+ max-height: 10em;
+ }
+
+ .video {
+ max-height: 10em;
+ }
+
+ input {
+ flex: 1;
+ width: 100%;
+ }
}
.status-input-wrapper {
@@ -490,23 +493,8 @@
.attachment {
margin: 0;
+ padding: 0;
position: relative;
- flex: 0 0 auto;
- border: 1px solid $fallback--border;
- border: 1px solid var(--border, $fallback--border);
- text-align: center;
-
- audio {
- min-width: 300px;
- flex: 1 0 auto;
- }
-
- a {
- display: block;
- text-align: left;
- line-height: 1.2;
- padding: .5em;
- }
}
i {
diff --git a/src/components/status_content/status_content.js b/src/components/status_content/status_content.js
index 09ea3a20..67d9bd3c 100644
--- a/src/components/status_content/status_content.js
+++ b/src/components/status_content/status_content.js
@@ -99,15 +99,8 @@ const StatusContent = {
file => !fileType.fileMatchesSomeType(this.galleryTypes, file)
)
},
- hasImageAttachments () {
- return this.status.attachments.some(
- file => fileType.fileType(file.mimetype) === 'image'
- )
- },
- hasVideoAttachments () {
- return this.status.attachments.some(
- file => fileType.fileType(file.mimetype) === 'video'
- )
+ attachmentTypes () {
+ return this.status.attachments.map(file => fileType.fileType(file.mimetype))
},
maxThumbnails () {
return this.mergedConfig.maxThumbnails
diff --git a/src/components/status_content/status_content.vue b/src/components/status_content/status_content.vue
index 40c28b5c..8068d8d2 100644
--- a/src/components/status_content/status_content.vue
+++ b/src/components/status_content/status_content.vue
@@ -55,14 +55,22 @@
>
{{ $t("status.show_content") }}
<span
- v-if="hasImageAttachments"
+ v-if="attachmentTypes.includes('image')"
class="icon-picture"
/>
<span
- v-if="hasVideoAttachments"
+ v-if="attachmentTypes.includes('video')"
class="icon-video"
/>
<span
+ v-if="attachmentTypes.includes('audio')"
+ class="icon-music"
+ />
+ <span
+ v-if="attachmentTypes.includes('unknown')"
+ class="icon-doc"
+ />
+ <span
v-if="status.card"
class="icon-link"
/>
diff --git a/src/components/still-image/still-image.js b/src/components/still-image/still-image.js
index e48fef47..ab40bbd7 100644
--- a/src/components/still-image/still-image.js
+++ b/src/components/still-image/still-image.js
@@ -4,7 +4,8 @@ const StillImage = {
'referrerpolicy',
'mimetype',
'imageLoadError',
- 'imageLoadHandler'
+ 'imageLoadHandler',
+ 'alt'
],
data () {
return {
diff --git a/src/components/still-image/still-image.vue b/src/components/still-image/still-image.vue
index f2ddeb7b..2ebf33ba 100644
--- a/src/components/still-image/still-image.vue
+++ b/src/components/still-image/still-image.vue
@@ -11,6 +11,8 @@
<img
ref="src"
:key="src"
+ :alt="alt"
+ :title="alt"
:src="src"
:referrerpolicy="referrerpolicy"
@load="onLoad"
diff --git a/src/components/video_attachment/video_attachment.vue b/src/components/video_attachment/video_attachment.vue
index 97ddf1cd..1ffed4e0 100644
--- a/src/components/video_attachment/video_attachment.vue
+++ b/src/components/video_attachment/video_attachment.vue
@@ -4,6 +4,8 @@
:src="attachment.url"
:loop="loopVideo"
:controls="controls"
+ :alt="attachment.description"
+ :title="attachment.description"
playsinline
@loadeddata="onVideoDataLoad"
/>