aboutsummaryrefslogtreecommitdiff
path: root/src/components
diff options
context:
space:
mode:
Diffstat (limited to 'src/components')
-rw-r--r--src/components/post_status_form/post_status_form.js52
-rw-r--r--src/components/post_status_form/post_status_form.vue113
2 files changed, 154 insertions, 11 deletions
diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index 9027566f..3f7e36a6 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 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'
@@ -38,7 +39,8 @@ const PostStatusForm = {
EmojiInput,
PollForm,
ScopeSelector,
- Checkbox
+ Checkbox,
+ StatusContent
},
mounted () {
this.resize(this.$refs.textarea)
@@ -84,7 +86,9 @@ const PostStatusForm = {
caret: 0,
pollFormVisible: false,
showDropIcon: 'hide',
- dropStopTimeout: null
+ dropStopTimeout: null,
+ preview: null,
+ previewLoading: false
}
},
computed: {
@@ -163,8 +167,20 @@ const PostStatusForm = {
this.newStatus.poll &&
this.newStatus.poll.error
},
+ showPreview () {
+ return !!this.preview || this.previewLoading
+ },
...mapGetters(['mergedConfig'])
},
+ watch: {
+ 'newStatus.contentType': function (newType) {
+ if (newType === 'text/plain') {
+ this.closePreview()
+ } else if (this.preview) {
+ this.previewStatus(this.newStatus)
+ }
+ }
+ },
methods: {
postStatus (newStatus) {
if (this.posting) { return }
@@ -218,6 +234,38 @@ const PostStatusForm = {
this.posting = false
})
},
+ previewStatus (newStatus) {
+ this.previewLoading = true
+ statusPoster.postStatus({
+ status: newStatus.status,
+ spoilerText: newStatus.spoilerText || null,
+ visibility: newStatus.visibility,
+ sensitive: newStatus.nsfw,
+ media: newStatus.files,
+ 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
+ })
+ },
+ closePreview () {
+ this.preview = null
+ this.previewLoading = false
+ },
addMediaFile (fileInfo) {
this.newStatus.files.push(fileInfo)
},
diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue
index e3d8d087..9931f5ca 100644
--- a/src/components/post_status_form/post_status_form.vue
+++ b/src/components/post_status_form/post_status_form.vue
@@ -16,6 +16,58 @@
@drop.stop="fileDrop"
/>
<div class="form-group">
+ <a
+ v-if="newStatus.contentType !== 'text/plain' && !showPreview"
+ class="preview-start faint"
+ type="button"
+ @click.stop.prevent="previewStatus(newStatus)"
+ >
+ {{ $t('status.preview') }}
+ </a>
+ <div
+ v-if="showPreview && newStatus.contentType !== 'text/plain'"
+ class="preview-container"
+ >
+ <span class="preview-heading">
+ <span class="faint preview-title">
+ {{ $t('status.status_preview') }}
+ </span>
+ <i
+ v-if="previewLoading"
+ class="icon-spin3 animate-spin"
+ />
+ <a
+ v-else
+ class="faint preview-update"
+ @click.stop.prevent="previewStatus(newStatus)"
+ >
+ {{ $t('status.preview_update') }}
+ </a>
+ <a
+ class="preview-close"
+ @click.stop.prevent="closePreview"
+ >
+ <i class="icon-cancel" />
+ </a>
+ </span>
+ <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>
<i18n
v-if="!$store.state.users.currentUser.locked && newStatus.visibility == 'private'"
path="post_status.account_not_locked_warning"
@@ -77,7 +129,6 @@
class="form-control"
>
<input
-
v-model="newStatus.spoilerText"
type="text"
:placeholder="$t('post_status.content_warning')"
@@ -303,14 +354,6 @@
}
.post-status-form {
- .visibility-tray {
- display: flex;
- justify-content: space-between;
- padding-top: 5px;
- }
-}
-
-.post-status-form {
.form-bottom {
display: flex;
justify-content: space-between;
@@ -336,6 +379,52 @@
max-width: 10em;
}
+ .preview-start {
+ margin-left: auto;
+ cursor: pointer;
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+
+ .preview-container {
+ margin-bottom: 1em;
+ }
+
+ .preview-heading {
+ display: flex;
+ width: 100%;
+ }
+
+ .preview-title {
+ flex-grow: 1;
+ }
+
+ .preview-close {
+ margin-left: 0.5em;
+ }
+
+ .preview-update {
+ cursor: pointer;
+ &:hover {
+ text-decoration: underline;
+ }
+ }
+
+ .preview-error {
+ color: $fallback--faint;
+ color: var(--faint, $fallback--faint);
+ font-style: italic;
+ }
+
+ .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;
+ }
+
.text-format {
.only-format {
color: $fallback--faint;
@@ -343,6 +432,12 @@
}
}
+ .visibility-tray {
+ display: flex;
+ justify-content: space-between;
+ padding-top: 5px;
+ }
+
.media-upload-icon, .poll-icon, .emoji-icon {
font-size: 26px;
flex: 1;