Merge branch 'xenofem/pleroma-fe-rebased-image-description-authoring' into 'develop'
media description authoring v3 See merge request pleroma/pleroma-fe!1161
This commit is contained in:
commit
ec26ff04ce
17 changed files with 186 additions and 105 deletions
|
@ -19,6 +19,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Autocomplete domains from list of known instances
|
- Autocomplete domains from list of known instances
|
||||||
- 'Bot' settings option and badge
|
- 'Bot' settings option and badge
|
||||||
- Added profile meta data fields that can be set in profile settings
|
- Added profile meta data fields that can be set in profile settings
|
||||||
|
- Descriptions can be set on uploaded files before posting
|
||||||
- Added status preview option to preview your statuses before posting
|
- Added status preview option to preview your statuses before posting
|
||||||
- When a post is a reply to an unavailable post, the 'Reply to'-text has a strike-through style
|
- When a post is a reply to an unavailable post, the 'Reply to'-text has a strike-through style
|
||||||
|
|
||||||
|
@ -28,6 +29,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Close the media modal on navigation events
|
- Close the media modal on navigation events
|
||||||
- Add colons to the emoji alt text, to make them copyable
|
- Add colons to the emoji alt text, to make them copyable
|
||||||
- Add better visual indication for drag-and-drop for files
|
- Add better visual indication for drag-and-drop for files
|
||||||
|
- When disabling attachments, the placeholder links now show an icon and the description instead of just IMAGE or VIDEO etc
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
- Custom Emoji will display in poll options now.
|
- Custom Emoji will display in poll options now.
|
||||||
|
@ -39,6 +41,10 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
|
||||||
- Subject field now appears disabled when posting
|
- Subject field now appears disabled when posting
|
||||||
- Fix status ellipsis menu being cut off in notifications column
|
- Fix status ellipsis menu being cut off in notifications column
|
||||||
- Fixed autocomplete sometimes not returning the right user when there's already some results
|
- Fixed autocomplete sometimes not returning the right user when there's already some results
|
||||||
|
- Videos and audio and misc files show description as alt/title properly now
|
||||||
|
- Clicking on non-image/video files no longer opens an empty modal
|
||||||
|
- Audio files can now be played back in the frontend with hidden attachments
|
||||||
|
- Videos are not cropped awkwardly in the uploads section anymore
|
||||||
- Reply filtering options in Settings -> Filtering now work again using filtering on server
|
- Reply filtering options in Settings -> Filtering now work again using filtering on server
|
||||||
- Don't show just blank-screen when cookies are disabled
|
- Don't show just blank-screen when cookies are disabled
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,6 @@ const Attachment = {
|
||||||
props: [
|
props: [
|
||||||
'attachment',
|
'attachment',
|
||||||
'nsfw',
|
'nsfw',
|
||||||
'statusId',
|
|
||||||
'size',
|
'size',
|
||||||
'allowPlay',
|
'allowPlay',
|
||||||
'setMedia',
|
'setMedia',
|
||||||
|
@ -30,9 +29,21 @@ const Attachment = {
|
||||||
VideoAttachment
|
VideoAttachment
|
||||||
},
|
},
|
||||||
computed: {
|
computed: {
|
||||||
usePlaceHolder () {
|
usePlaceholder () {
|
||||||
return this.size === 'hide' || this.type === 'unknown'
|
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 () {
|
referrerpolicy () {
|
||||||
return this.$store.state.instance.mediaProxyAvailable ? '' : 'no-referrer'
|
return this.$store.state.instance.mediaProxyAvailable ? '' : 'no-referrer'
|
||||||
},
|
},
|
||||||
|
@ -49,7 +60,15 @@ const Attachment = {
|
||||||
return this.size === 'small'
|
return this.size === 'small'
|
||||||
},
|
},
|
||||||
fullwidth () {
|
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'])
|
...mapGetters(['mergedConfig'])
|
||||||
},
|
},
|
||||||
|
@ -60,12 +79,7 @@ const Attachment = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
openModal (event) {
|
openModal (event) {
|
||||||
const modalTypes = this.mergedConfig.playVideosInModal
|
if (this.useModal) {
|
||||||
? ['image', 'video']
|
|
||||||
: ['image']
|
|
||||||
if (fileTypeService.fileMatchesSomeType(modalTypes, this.attachment) ||
|
|
||||||
this.usePlaceHolder
|
|
||||||
) {
|
|
||||||
event.stopPropagation()
|
event.stopPropagation()
|
||||||
event.preventDefault()
|
event.preventDefault()
|
||||||
this.setMedia()
|
this.setMedia()
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
v-if="usePlaceHolder"
|
v-if="usePlaceholder"
|
||||||
|
:class="{ 'fullwidth': fullwidth }"
|
||||||
@click="openModal"
|
@click="openModal"
|
||||||
>
|
>
|
||||||
<a
|
<a
|
||||||
|
@ -8,8 +9,11 @@
|
||||||
class="placeholder"
|
class="placeholder"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
:href="attachment.url"
|
:href="attachment.url"
|
||||||
|
:alt="attachment.description"
|
||||||
|
:title="attachment.description"
|
||||||
>
|
>
|
||||||
[{{ nsfw ? "NSFW/" : "" }}{{ type.toUpperCase() }}]
|
<span :class="placeholderIconClass" />
|
||||||
|
<b>{{ nsfw ? "NSFW / " : "" }}</b>{{ placeholderName }}
|
||||||
</a>
|
</a>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -22,6 +26,8 @@
|
||||||
v-if="hidden"
|
v-if="hidden"
|
||||||
class="image-attachment"
|
class="image-attachment"
|
||||||
:href="attachment.url"
|
:href="attachment.url"
|
||||||
|
:alt="attachment.description"
|
||||||
|
:title="attachment.description"
|
||||||
@click.prevent="toggleHidden"
|
@click.prevent="toggleHidden"
|
||||||
>
|
>
|
||||||
<img
|
<img
|
||||||
|
@ -51,7 +57,6 @@
|
||||||
:class="{'hidden': hidden && preloadImage }"
|
:class="{'hidden': hidden && preloadImage }"
|
||||||
:href="attachment.url"
|
:href="attachment.url"
|
||||||
target="_blank"
|
target="_blank"
|
||||||
:title="attachment.description"
|
|
||||||
@click="openModal"
|
@click="openModal"
|
||||||
>
|
>
|
||||||
<StillImage
|
<StillImage
|
||||||
|
@ -59,6 +64,7 @@
|
||||||
:mimetype="attachment.mimetype"
|
:mimetype="attachment.mimetype"
|
||||||
:src="attachment.large_thumb_url || attachment.url"
|
:src="attachment.large_thumb_url || attachment.url"
|
||||||
:image-load-handler="onImageLoad"
|
:image-load-handler="onImageLoad"
|
||||||
|
:alt="attachment.description"
|
||||||
/>
|
/>
|
||||||
</a>
|
</a>
|
||||||
|
|
||||||
|
@ -83,6 +89,8 @@
|
||||||
<audio
|
<audio
|
||||||
v-if="type === 'audio'"
|
v-if="type === 'audio'"
|
||||||
:src="attachment.url"
|
:src="attachment.url"
|
||||||
|
:alt="attachment.description"
|
||||||
|
:title="attachment.description"
|
||||||
controls
|
controls
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
@ -116,22 +124,19 @@
|
||||||
display: flex;
|
display: flex;
|
||||||
flex-wrap: wrap;
|
flex-wrap: wrap;
|
||||||
|
|
||||||
.attachment.media-upload-container {
|
.non-gallery {
|
||||||
flex: 0 0 auto;
|
|
||||||
max-height: 200px;
|
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
video {
|
|
||||||
max-width: 100%;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.placeholder {
|
.placeholder {
|
||||||
margin-right: 8px;
|
display: inline-block;
|
||||||
margin-bottom: 4px;
|
padding: 0.3em 1em 0.3em 0;
|
||||||
color: $fallback--link;
|
color: $fallback--link;
|
||||||
color: var(--postLink, $fallback--link);
|
color: var(--postLink, $fallback--link);
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
max-width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nsfw-placeholder {
|
.nsfw-placeholder {
|
||||||
|
|
|
@ -50,9 +50,7 @@
|
||||||
align-content: stretch;
|
align-content: stretch;
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME: specificity problem with this and .attachments.attachment
|
.gallery-row-inner .attachment {
|
||||||
// we shouldn't have the need for .image here
|
|
||||||
.attachment.image {
|
|
||||||
margin: 0 0.5em 0 0;
|
margin: 0 0.5em 0 0;
|
||||||
flex-grow: 1;
|
flex-grow: 1;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
|
|
@ -8,6 +8,8 @@
|
||||||
v-if="type === 'image'"
|
v-if="type === 'image'"
|
||||||
class="modal-image"
|
class="modal-image"
|
||||||
:src="currentMedia.url"
|
:src="currentMedia.url"
|
||||||
|
:alt="currentMedia.description"
|
||||||
|
:title="currentMedia.description"
|
||||||
@touchstart.stop="mediaTouchStart"
|
@touchstart.stop="mediaTouchStart"
|
||||||
@touchmove.stop="mediaTouchMove"
|
@touchmove.stop="mediaTouchMove"
|
||||||
@click="hide"
|
@click="hide"
|
||||||
|
@ -18,6 +20,14 @@
|
||||||
:attachment="currentMedia"
|
:attachment="currentMedia"
|
||||||
:controls="true"
|
:controls="true"
|
||||||
/>
|
/>
|
||||||
|
<audio
|
||||||
|
v-if="type === 'audio'"
|
||||||
|
class="modal-image"
|
||||||
|
:src="currentMedia.url"
|
||||||
|
:alt="currentMedia.description"
|
||||||
|
:title="currentMedia.description"
|
||||||
|
controls
|
||||||
|
/>
|
||||||
<button
|
<button
|
||||||
v-if="canNavigate"
|
v-if="canNavigate"
|
||||||
:title="$t('media_modal.previous')"
|
:title="$t('media_modal.previous')"
|
||||||
|
|
|
@ -3,6 +3,7 @@ import MediaUpload from '../media_upload/media_upload.vue'
|
||||||
import ScopeSelector from '../scope_selector/scope_selector.vue'
|
import ScopeSelector from '../scope_selector/scope_selector.vue'
|
||||||
import EmojiInput from '../emoji_input/emoji_input.vue'
|
import EmojiInput from '../emoji_input/emoji_input.vue'
|
||||||
import PollForm from '../poll/poll_form.vue'
|
import PollForm from '../poll/poll_form.vue'
|
||||||
|
import Attachment from '../attachment/attachment.vue'
|
||||||
import StatusContent from '../status_content/status_content.vue'
|
import StatusContent from '../status_content/status_content.vue'
|
||||||
import fileTypeService from '../../services/file_type/file_type.service.js'
|
import fileTypeService from '../../services/file_type/file_type.service.js'
|
||||||
import { findOffset } from '../../services/offset_finder/offset_finder.service.js'
|
import { findOffset } from '../../services/offset_finder/offset_finder.service.js'
|
||||||
|
@ -40,6 +41,7 @@ const PostStatusForm = {
|
||||||
PollForm,
|
PollForm,
|
||||||
ScopeSelector,
|
ScopeSelector,
|
||||||
Checkbox,
|
Checkbox,
|
||||||
|
Attachment,
|
||||||
StatusContent
|
StatusContent
|
||||||
},
|
},
|
||||||
mounted () {
|
mounted () {
|
||||||
|
@ -80,6 +82,7 @@ const PostStatusForm = {
|
||||||
nsfw: false,
|
nsfw: false,
|
||||||
files: [],
|
files: [],
|
||||||
poll: {},
|
poll: {},
|
||||||
|
mediaDescriptions: {},
|
||||||
visibility: scope,
|
visibility: scope,
|
||||||
contentType
|
contentType
|
||||||
},
|
},
|
||||||
|
@ -184,7 +187,7 @@ const PostStatusForm = {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
methods: {
|
methods: {
|
||||||
postStatus (newStatus) {
|
async postStatus (newStatus) {
|
||||||
if (this.posting) { return }
|
if (this.posting) { return }
|
||||||
if (this.submitDisabled) { return }
|
if (this.submitDisabled) { return }
|
||||||
if (this.emptyStatus) {
|
if (this.emptyStatus) {
|
||||||
|
@ -199,7 +202,16 @@ const PostStatusForm = {
|
||||||
}
|
}
|
||||||
|
|
||||||
this.posting = true
|
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,
|
status: newStatus.status,
|
||||||
spoilerText: newStatus.spoilerText || null,
|
spoilerText: newStatus.spoilerText || null,
|
||||||
visibility: newStatus.visibility,
|
visibility: newStatus.visibility,
|
||||||
|
@ -209,7 +221,8 @@ const PostStatusForm = {
|
||||||
inReplyToStatusId: this.replyTo,
|
inReplyToStatusId: this.replyTo,
|
||||||
contentType: newStatus.contentType,
|
contentType: newStatus.contentType,
|
||||||
poll
|
poll
|
||||||
}).then((data) => {
|
})
|
||||||
|
|
||||||
if (!data.error) {
|
if (!data.error) {
|
||||||
this.newStatus = {
|
this.newStatus = {
|
||||||
status: '',
|
status: '',
|
||||||
|
@ -217,7 +230,8 @@ const PostStatusForm = {
|
||||||
files: [],
|
files: [],
|
||||||
visibility: newStatus.visibility,
|
visibility: newStatus.visibility,
|
||||||
contentType: newStatus.contentType,
|
contentType: newStatus.contentType,
|
||||||
poll: {}
|
poll: {},
|
||||||
|
mediaDescriptions: {}
|
||||||
}
|
}
|
||||||
this.pollFormVisible = false
|
this.pollFormVisible = false
|
||||||
this.$refs.mediaUpload.clearFile()
|
this.$refs.mediaUpload.clearFile()
|
||||||
|
@ -231,8 +245,8 @@ const PostStatusForm = {
|
||||||
} else {
|
} else {
|
||||||
this.error = data.error
|
this.error = data.error
|
||||||
}
|
}
|
||||||
|
|
||||||
this.posting = false
|
this.posting = false
|
||||||
})
|
|
||||||
},
|
},
|
||||||
previewStatus () {
|
previewStatus () {
|
||||||
if (this.emptyStatus && this.newStatus.spoilerText.trim() === '') {
|
if (this.emptyStatus && this.newStatus.spoilerText.trim() === '') {
|
||||||
|
@ -457,6 +471,15 @@ const PostStatusForm = {
|
||||||
},
|
},
|
||||||
dismissScopeNotice () {
|
dismissScopeNotice () {
|
||||||
this.$store.dispatch('setOption', { name: 'hideScopeNotice', value: true })
|
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)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -282,27 +282,18 @@
|
||||||
class="fa button-icon icon-cancel"
|
class="fa button-icon icon-cancel"
|
||||||
@click="removeMediaFile(file)"
|
@click="removeMediaFile(file)"
|
||||||
/>
|
/>
|
||||||
<div class="media-upload-container attachment">
|
<attachment
|
||||||
<img
|
:attachment="file"
|
||||||
v-if="type(file) === 'image'"
|
:set-media="() => $store.dispatch('setMedia', newStatus.files)"
|
||||||
class="thumbnail media-upload"
|
size="small"
|
||||||
:src="file.url"
|
allow-play="false"
|
||||||
|
/>
|
||||||
|
<input
|
||||||
|
v-model="newStatus.mediaDescriptions[file.id]"
|
||||||
|
type="text"
|
||||||
|
:placeholder="$t('post_status.media_description')"
|
||||||
|
@keydown.enter.prevent=""
|
||||||
>
|
>
|
||||||
<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>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
|
@ -458,11 +449,9 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.media-upload-wrapper {
|
.media-upload-wrapper {
|
||||||
flex: 0 0 auto;
|
|
||||||
max-width: 100%;
|
|
||||||
min-width: 50px;
|
|
||||||
margin-right: .2em;
|
margin-right: .2em;
|
||||||
margin-bottom: .5em;
|
margin-bottom: .5em;
|
||||||
|
width: 18em;
|
||||||
|
|
||||||
.icon-cancel {
|
.icon-cancel {
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
|
@ -476,6 +465,20 @@
|
||||||
border-bottom-left-radius: 0;
|
border-bottom-left-radius: 0;
|
||||||
border-bottom-right-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 {
|
.status-input-wrapper {
|
||||||
|
@ -490,23 +493,8 @@
|
||||||
|
|
||||||
.attachment {
|
.attachment {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
position: relative;
|
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 {
|
i {
|
||||||
|
|
|
@ -99,15 +99,8 @@ const StatusContent = {
|
||||||
file => !fileType.fileMatchesSomeType(this.galleryTypes, file)
|
file => !fileType.fileMatchesSomeType(this.galleryTypes, file)
|
||||||
)
|
)
|
||||||
},
|
},
|
||||||
hasImageAttachments () {
|
attachmentTypes () {
|
||||||
return this.status.attachments.some(
|
return this.status.attachments.map(file => fileType.fileType(file.mimetype))
|
||||||
file => fileType.fileType(file.mimetype) === 'image'
|
|
||||||
)
|
|
||||||
},
|
|
||||||
hasVideoAttachments () {
|
|
||||||
return this.status.attachments.some(
|
|
||||||
file => fileType.fileType(file.mimetype) === 'video'
|
|
||||||
)
|
|
||||||
},
|
},
|
||||||
maxThumbnails () {
|
maxThumbnails () {
|
||||||
return this.mergedConfig.maxThumbnails
|
return this.mergedConfig.maxThumbnails
|
||||||
|
|
|
@ -55,13 +55,21 @@
|
||||||
>
|
>
|
||||||
{{ $t("status.show_content") }}
|
{{ $t("status.show_content") }}
|
||||||
<span
|
<span
|
||||||
v-if="hasImageAttachments"
|
v-if="attachmentTypes.includes('image')"
|
||||||
class="icon-picture"
|
class="icon-picture"
|
||||||
/>
|
/>
|
||||||
<span
|
<span
|
||||||
v-if="hasVideoAttachments"
|
v-if="attachmentTypes.includes('video')"
|
||||||
class="icon-video"
|
class="icon-video"
|
||||||
/>
|
/>
|
||||||
|
<span
|
||||||
|
v-if="attachmentTypes.includes('audio')"
|
||||||
|
class="icon-music"
|
||||||
|
/>
|
||||||
|
<span
|
||||||
|
v-if="attachmentTypes.includes('unknown')"
|
||||||
|
class="icon-doc"
|
||||||
|
/>
|
||||||
<span
|
<span
|
||||||
v-if="status.card"
|
v-if="status.card"
|
||||||
class="icon-link"
|
class="icon-link"
|
||||||
|
|
|
@ -4,7 +4,8 @@ const StillImage = {
|
||||||
'referrerpolicy',
|
'referrerpolicy',
|
||||||
'mimetype',
|
'mimetype',
|
||||||
'imageLoadError',
|
'imageLoadError',
|
||||||
'imageLoadHandler'
|
'imageLoadHandler',
|
||||||
|
'alt'
|
||||||
],
|
],
|
||||||
data () {
|
data () {
|
||||||
return {
|
return {
|
||||||
|
|
|
@ -11,6 +11,8 @@
|
||||||
<img
|
<img
|
||||||
ref="src"
|
ref="src"
|
||||||
:key="src"
|
:key="src"
|
||||||
|
:alt="alt"
|
||||||
|
:title="alt"
|
||||||
:src="src"
|
:src="src"
|
||||||
:referrerpolicy="referrerpolicy"
|
:referrerpolicy="referrerpolicy"
|
||||||
@load="onLoad"
|
@load="onLoad"
|
||||||
|
|
|
@ -4,6 +4,8 @@
|
||||||
:src="attachment.url"
|
:src="attachment.url"
|
||||||
:loop="loopVideo"
|
:loop="loopVideo"
|
||||||
:controls="controls"
|
:controls="controls"
|
||||||
|
:alt="attachment.description"
|
||||||
|
:title="attachment.description"
|
||||||
playsinline
|
playsinline
|
||||||
@loadeddata="onVideoDataLoad"
|
@loadeddata="onVideoDataLoad"
|
||||||
/>
|
/>
|
||||||
|
|
|
@ -178,6 +178,7 @@
|
||||||
"account_not_locked_warning": "Your account is not {0}. Anyone can follow you to view your follower-only posts.",
|
"account_not_locked_warning": "Your account is not {0}. Anyone can follow you to view your follower-only posts.",
|
||||||
"account_not_locked_warning_link": "locked",
|
"account_not_locked_warning_link": "locked",
|
||||||
"attachments_sensitive": "Mark attachments as sensitive",
|
"attachments_sensitive": "Mark attachments as sensitive",
|
||||||
|
"media_description": "Media description",
|
||||||
"content_type": {
|
"content_type": {
|
||||||
"text/plain": "Plain text",
|
"text/plain": "Plain text",
|
||||||
"text/html": "HTML",
|
"text/html": "HTML",
|
||||||
|
@ -192,6 +193,7 @@
|
||||||
"preview": "Preview",
|
"preview": "Preview",
|
||||||
"preview_empty": "Empty",
|
"preview_empty": "Empty",
|
||||||
"empty_status_error": "Can't post an empty status with no files",
|
"empty_status_error": "Can't post an empty status with no files",
|
||||||
|
"media_description_error": "Failed to update media, try again",
|
||||||
"scope_notice": {
|
"scope_notice": {
|
||||||
"public": "This post will be visible to everyone",
|
"public": "This post will be visible to everyone",
|
||||||
"private": "This post will be visible to your followers only",
|
"private": "This post will be visible to your followers only",
|
||||||
|
|
|
@ -22,7 +22,7 @@ const mediaViewer = {
|
||||||
setMedia ({ commit }, attachments) {
|
setMedia ({ commit }, attachments) {
|
||||||
const media = attachments.filter(attachment => {
|
const media = attachments.filter(attachment => {
|
||||||
const type = fileTypeService.fileType(attachment.mimetype)
|
const type = fileTypeService.fileType(attachment.mimetype)
|
||||||
return type === 'image' || type === 'video'
|
return type === 'image' || type === 'video' || type === 'audio'
|
||||||
})
|
})
|
||||||
commit('setMedia', media)
|
commit('setMedia', media)
|
||||||
},
|
},
|
||||||
|
|
|
@ -708,6 +708,17 @@ const uploadMedia = ({ formData, credentials }) => {
|
||||||
.then((data) => parseAttachment(data))
|
.then((data) => parseAttachment(data))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setMediaDescription = ({ id, description, credentials }) => {
|
||||||
|
return promisedRequest({
|
||||||
|
url: `${MASTODON_MEDIA_UPLOAD_URL}/${id}`,
|
||||||
|
method: 'PUT',
|
||||||
|
headers: authHeaders(credentials),
|
||||||
|
payload: {
|
||||||
|
description
|
||||||
|
}
|
||||||
|
}).then((data) => parseAttachment(data))
|
||||||
|
}
|
||||||
|
|
||||||
const importBlocks = ({ file, credentials }) => {
|
const importBlocks = ({ file, credentials }) => {
|
||||||
const formData = new FormData()
|
const formData = new FormData()
|
||||||
formData.append('list', file)
|
formData.append('list', file)
|
||||||
|
@ -1177,6 +1188,7 @@ const apiService = {
|
||||||
postStatus,
|
postStatus,
|
||||||
deleteStatus,
|
deleteStatus,
|
||||||
uploadMedia,
|
uploadMedia,
|
||||||
|
setMediaDescription,
|
||||||
fetchMutes,
|
fetchMutes,
|
||||||
muteUser,
|
muteUser,
|
||||||
unmuteUser,
|
unmuteUser,
|
||||||
|
|
|
@ -47,13 +47,18 @@ const postStatus = ({
|
||||||
|
|
||||||
const uploadMedia = ({ store, formData }) => {
|
const uploadMedia = ({ store, formData }) => {
|
||||||
const credentials = store.state.users.currentUser.credentials
|
const credentials = store.state.users.currentUser.credentials
|
||||||
|
|
||||||
return apiService.uploadMedia({ credentials, formData })
|
return apiService.uploadMedia({ credentials, formData })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const setMediaDescription = ({ store, id, description }) => {
|
||||||
|
const credentials = store.state.users.currentUser.credentials
|
||||||
|
return apiService.setMediaDescription({ credentials, id, description })
|
||||||
|
}
|
||||||
|
|
||||||
const statusPosterService = {
|
const statusPosterService = {
|
||||||
postStatus,
|
postStatus,
|
||||||
uploadMedia
|
uploadMedia,
|
||||||
|
setMediaDescription
|
||||||
}
|
}
|
||||||
|
|
||||||
export default statusPosterService
|
export default statusPosterService
|
||||||
|
|
|
@ -387,6 +387,18 @@
|
||||||
"css": "bookmark-empty",
|
"css": "bookmark-empty",
|
||||||
"code": 61591,
|
"code": 61591,
|
||||||
"src": "fontawesome"
|
"src": "fontawesome"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": "9ea0a737ccc45d6c510dcbae56058849",
|
||||||
|
"css": "music",
|
||||||
|
"code": 59432,
|
||||||
|
"src": "fontawesome"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"uid": "1b5a5d7b7e3c71437f5a26befdd045ed",
|
||||||
|
"css": "doc",
|
||||||
|
"code": 59433,
|
||||||
|
"src": "fontawesome"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
Loading…
Reference in a new issue