fix conflicts and add error handling to media descriptions
This commit is contained in:
commit
e3991db5c4
9 changed files with 202 additions and 39 deletions
|
@ -4,9 +4,10 @@ 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'
|
||||
import { reject, map, uniqBy } from 'lodash'
|
||||
import { reject, map, uniqBy, debounce } from 'lodash'
|
||||
import suggestor from '../emoji_input/suggestor.js'
|
||||
import { mapGetters } from 'vuex'
|
||||
import Checkbox from '../checkbox/checkbox.vue'
|
||||
|
@ -40,7 +41,8 @@ const PostStatusForm = {
|
|||
PollForm,
|
||||
ScopeSelector,
|
||||
Checkbox,
|
||||
Attachment
|
||||
Attachment,
|
||||
StatusContent
|
||||
},
|
||||
mounted () {
|
||||
this.resize(this.$refs.textarea)
|
||||
|
@ -87,7 +89,9 @@ const PostStatusForm = {
|
|||
caret: 0,
|
||||
pollFormVisible: false,
|
||||
showDropIcon: 'hide',
|
||||
dropStopTimeout: null
|
||||
dropStopTimeout: null,
|
||||
preview: null,
|
||||
previewLoading: false
|
||||
}
|
||||
},
|
||||
computed: {
|
||||
|
@ -166,18 +170,29 @@ const PostStatusForm = {
|
|||
this.newStatus.poll &&
|
||||
this.newStatus.poll.error
|
||||
},
|
||||
showPreview () {
|
||||
return !!this.preview || this.previewLoading
|
||||
},
|
||||
emptyStatus () {
|
||||
return this.newStatus.status.trim() === '' && this.newStatus.files.length === 0
|
||||
},
|
||||
...mapGetters(['mergedConfig'])
|
||||
},
|
||||
watch: {
|
||||
'newStatus.contentType': function () {
|
||||
this.autoPreview()
|
||||
},
|
||||
'newStatus.spoilerText': function () {
|
||||
this.autoPreview()
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
async postStatus (newStatus) {
|
||||
if (this.posting) { return }
|
||||
if (this.submitDisabled) { return }
|
||||
|
||||
if (this.newStatus.status === '') {
|
||||
if (this.newStatus.files.length === 0) {
|
||||
this.error = 'Cannot post an empty status with no files'
|
||||
return
|
||||
}
|
||||
if (this.emptyStatus) {
|
||||
this.error = this.$t('post_status.empty_status_error')
|
||||
return
|
||||
}
|
||||
|
||||
const poll = this.pollFormVisible ? this.newStatus.poll : {}
|
||||
|
@ -188,7 +203,13 @@ const PostStatusForm = {
|
|||
|
||||
this.posting = true
|
||||
|
||||
await this.setAllMediaDescriptions()
|
||||
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,
|
||||
|
@ -219,12 +240,64 @@ const PostStatusForm = {
|
|||
el.style.height = 'auto'
|
||||
el.style.height = undefined
|
||||
this.error = null
|
||||
this.previewStatus()
|
||||
} else {
|
||||
this.error = data.error
|
||||
}
|
||||
|
||||
this.posting = false
|
||||
},
|
||||
previewStatus () {
|
||||
if (this.emptyStatus && this.newStatus.spoilerText.trim() === '') {
|
||||
this.preview = { error: this.$t('post_status.preview_empty') }
|
||||
this.previewLoading = false
|
||||
return
|
||||
}
|
||||
const newStatus = this.newStatus
|
||||
this.previewLoading = true
|
||||
statusPoster.postStatus({
|
||||
status: newStatus.status,
|
||||
spoilerText: newStatus.spoilerText || null,
|
||||
visibility: newStatus.visibility,
|
||||
sensitive: newStatus.nsfw,
|
||||
media: [],
|
||||
store: this.$store,
|
||||
inReplyToStatusId: this.replyTo,
|
||||
contentType: newStatus.contentType,
|
||||
poll: {},
|
||||
preview: true
|
||||
}).then((data) => {
|
||||
// Don't apply preview if not loading, because it means
|
||||
// user has closed the preview manually.
|
||||
if (!this.previewLoading) return
|
||||
if (!data.error) {
|
||||
this.preview = data
|
||||
} else {
|
||||
this.preview = { error: data.error }
|
||||
}
|
||||
}).catch((error) => {
|
||||
this.preview = { error }
|
||||
}).finally(() => {
|
||||
this.previewLoading = false
|
||||
})
|
||||
},
|
||||
debouncePreviewStatus: debounce(function () { this.previewStatus() }, 500),
|
||||
autoPreview () {
|
||||
if (!this.preview) return
|
||||
this.previewLoading = true
|
||||
this.debouncePreviewStatus()
|
||||
},
|
||||
closePreview () {
|
||||
this.preview = null
|
||||
this.previewLoading = false
|
||||
},
|
||||
togglePreview () {
|
||||
if (this.showPreview) {
|
||||
this.closePreview()
|
||||
} else {
|
||||
this.previewStatus()
|
||||
}
|
||||
},
|
||||
addMediaFile (fileInfo) {
|
||||
this.newStatus.files.push(fileInfo)
|
||||
},
|
||||
|
@ -246,6 +319,7 @@ const PostStatusForm = {
|
|||
return fileTypeService.fileType(fileInfo.mimetype)
|
||||
},
|
||||
paste (e) {
|
||||
this.autoPreview()
|
||||
this.resize(e)
|
||||
if (e.clipboardData.files.length > 0) {
|
||||
// prevent pasting of file as text
|
||||
|
@ -280,6 +354,7 @@ const PostStatusForm = {
|
|||
}
|
||||
},
|
||||
onEmojiInputInput (e) {
|
||||
this.autoPreview()
|
||||
this.$nextTick(() => {
|
||||
this.resize(this.$refs['textarea'])
|
||||
})
|
||||
|
|
|
@ -69,6 +69,44 @@
|
|||
<span v-if="safeDMEnabled">{{ $t('post_status.direct_warning_to_first_only') }}</span>
|
||||
<span v-else>{{ $t('post_status.direct_warning_to_all') }}</span>
|
||||
</p>
|
||||
<div class="preview-heading faint">
|
||||
<a
|
||||
class="preview-toggle faint"
|
||||
@click.stop.prevent="togglePreview"
|
||||
>
|
||||
{{ $t('post_status.preview') }}
|
||||
<i
|
||||
class="icon-down-open"
|
||||
:style="{ transform: showPreview ? 'rotate(0deg)' : 'rotate(-90deg)' }"
|
||||
/>
|
||||
</a>
|
||||
<i
|
||||
v-show="previewLoading"
|
||||
class="icon-spin3 animate-spin"
|
||||
/>
|
||||
</div>
|
||||
<div
|
||||
v-if="showPreview"
|
||||
class="preview-container"
|
||||
>
|
||||
<div
|
||||
v-if="!preview"
|
||||
class="preview-status"
|
||||
>
|
||||
{{ $t('general.loading') }}
|
||||
</div>
|
||||
<div
|
||||
v-else-if="preview.error"
|
||||
class="preview-status preview-error"
|
||||
>
|
||||
{{ preview.error }}
|
||||
</div>
|
||||
<StatusContent
|
||||
v-else
|
||||
:status="preview"
|
||||
class="preview-status"
|
||||
/>
|
||||
</div>
|
||||
<EmojiInput
|
||||
v-if="newStatus.spoilerText || alwaysShowSubject"
|
||||
v-model="newStatus.spoilerText"
|
||||
|
@ -77,7 +115,6 @@
|
|||
class="form-control"
|
||||
>
|
||||
<input
|
||||
|
||||
v-model="newStatus.spoilerText"
|
||||
type="text"
|
||||
:placeholder="$t('post_status.content_warning')"
|
||||
|
@ -293,14 +330,6 @@
|
|||
}
|
||||
}
|
||||
|
||||
.post-status-form {
|
||||
.visibility-tray {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding-top: 5px;
|
||||
}
|
||||
}
|
||||
|
||||
.post-status-form {
|
||||
.form-bottom {
|
||||
display: flex;
|
||||
|
@ -327,6 +356,48 @@
|
|||
max-width: 10em;
|
||||
}
|
||||
|
||||
.preview-heading {
|
||||
display: flex;
|
||||
width: 100%;
|
||||
|
||||
.icon-spin3 {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
||||
.preview-toggle {
|
||||
display: flex;
|
||||
cursor: pointer;
|
||||
|
||||
&:hover {
|
||||
text-decoration: underline;
|
||||
}
|
||||
}
|
||||
|
||||
.icon-down-open {
|
||||
transition: transform 0.1s;
|
||||
}
|
||||
|
||||
.preview-container {
|
||||
margin-bottom: 1em;
|
||||
}
|
||||
|
||||
.preview-error {
|
||||
font-style: italic;
|
||||
color: $fallback--faint;
|
||||
color: var(--faint, $fallback--faint);
|
||||
}
|
||||
|
||||
.preview-status {
|
||||
border: 1px solid $fallback--border;
|
||||
border: 1px solid var(--border, $fallback--border);
|
||||
border-radius: $fallback--tooltipRadius;
|
||||
border-radius: var(--tooltipRadius, $fallback--tooltipRadius);
|
||||
padding: 0.5em;
|
||||
margin: 0;
|
||||
line-height: 1.4em;
|
||||
}
|
||||
|
||||
.text-format {
|
||||
.only-format {
|
||||
color: $fallback--faint;
|
||||
|
@ -334,6 +405,12 @@
|
|||
}
|
||||
}
|
||||
|
||||
.visibility-tray {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
padding-top: 5px;
|
||||
}
|
||||
|
||||
.media-upload-icon, .poll-icon, .emoji-icon {
|
||||
font-size: 26px;
|
||||
flex: 1;
|
||||
|
@ -411,7 +488,7 @@
|
|||
flex-direction: column;
|
||||
}
|
||||
|
||||
.attachments {
|
||||
.media-upload-wrapper .attachments {
|
||||
padding: 0 0.5em;
|
||||
|
||||
.attachment {
|
||||
|
|
|
@ -377,9 +377,6 @@ $status-margin: 0.75em;
|
|||
}
|
||||
|
||||
.status-el {
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
border-left-width: 0px;
|
||||
min-width: 0;
|
||||
border-color: $fallback--border;
|
||||
|
|
|
@ -225,6 +225,9 @@ $status-margin: 0.75em;
|
|||
font-family: var(--postFont, sans-serif);
|
||||
line-height: 1.4em;
|
||||
white-space: pre-wrap;
|
||||
overflow-wrap: break-word;
|
||||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
|
||||
blockquote {
|
||||
margin: 0.2em 0 0.2em 2em;
|
||||
|
|
|
@ -10,9 +10,7 @@
|
|||
:hide-bio="true"
|
||||
rounded="top"
|
||||
/>
|
||||
<div class="panel-footer">
|
||||
<PostStatusForm />
|
||||
</div>
|
||||
<PostStatusForm />
|
||||
</div>
|
||||
<auth-form
|
||||
v-else
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue