From 223fabfe90512122ee9d51c22deb01241ba931cd Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Sun, 28 Jun 2020 12:16:41 +0300 Subject: [PATCH 01/12] add rich text preview --- .../post_status_form/post_status_form.js | 52 +++++++- .../post_status_form/post_status_form.vue | 113 ++++++++++++++++-- src/i18n/en.json | 5 +- src/services/api/api.service.js | 14 +-- .../status_poster/status_poster.service.js | 19 ++- 5 files changed, 180 insertions(+), 23 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" />
+ + {{ $t('status.preview') }} + +
+ + + {{ $t('status.status_preview') }} + + + + {{ $t('status.preview_update') }} + + + + + +
+ {{ $t('general.loading') }} +
+
+ {{ preview.error }} +
+ +
{ const form = new FormData() const pollOptions = poll.options || [] @@ -647,6 +648,9 @@ const postStatus = ({ if (inReplyToStatusId) { form.append('in_reply_to_id', inReplyToStatusId) } + if (preview) { + form.append('preview', 'true') + } return fetch(MASTODON_POST_STATUS_URL, { body: form, @@ -654,13 +658,7 @@ const postStatus = ({ headers: authHeaders(credentials) }) .then((response) => { - if (response.ok) { - return response.json() - } else { - return { - error: response - } - } + return response.json() }) .then((data) => data.error ? data : parseStatus(data)) } diff --git a/src/services/status_poster/status_poster.service.js b/src/services/status_poster/status_poster.service.js index 9e904d3a..86fc5601 100644 --- a/src/services/status_poster/status_poster.service.js +++ b/src/services/status_poster/status_poster.service.js @@ -1,7 +1,18 @@ import { map } from 'lodash' import apiService from '../api/api.service.js' -const postStatus = ({ store, status, spoilerText, visibility, sensitive, poll, media = [], inReplyToStatusId = undefined, contentType = 'text/plain' }) => { +const postStatus = ({ + store, + status, + spoilerText, + visibility, + sensitive, + poll, + media = [], + inReplyToStatusId = undefined, + contentType = 'text/plain', + preview = false +}) => { const mediaIds = map(media, 'id') return apiService.postStatus({ @@ -13,9 +24,11 @@ const postStatus = ({ store, status, spoilerText, visibility, sensitive, poll, m mediaIds, inReplyToStatusId, contentType, - poll }) + poll, + preview + }) .then((data) => { - if (!data.error) { + if (!data.error && !preview) { store.dispatch('addNewStatuses', { statuses: [data], timeline: 'friends', From 3d5da3caf99e4a81e1837ecf2c7dc94defbfb569 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Sun, 28 Jun 2020 12:35:05 +0300 Subject: [PATCH 02/12] update styles in preview heading --- .../post_status_form/post_status_form.vue | 16 ++++++---------- 1 file changed, 6 insertions(+), 10 deletions(-) diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 9931f5ca..848d6af7 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -18,7 +18,7 @@
@@ -29,7 +29,7 @@ class="preview-container" > - + {{ $t('status.status_preview') }} {{ $t('status.preview_update') }} @@ -382,9 +382,6 @@ .preview-start { margin-left: auto; cursor: pointer; - &:hover { - text-decoration: underline; - } } .preview-container { @@ -394,6 +391,8 @@ .preview-heading { display: flex; width: 100%; + color: $fallback--faint; + color: var(--faint, $fallback--faint); } .preview-title { @@ -406,15 +405,12 @@ .preview-update { cursor: pointer; - &:hover { - text-decoration: underline; - } } .preview-error { + font-style: italic; color: $fallback--faint; color: var(--faint, $fallback--faint); - font-style: italic; } .preview-status { From 9d6f2332024a86a6d51ec92fd2fb77e27f749fd1 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Sun, 28 Jun 2020 12:48:17 +0300 Subject: [PATCH 03/12] fix preview attachments getting wrong styles --- src/components/post_status_form/post_status_form.vue | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 848d6af7..31fac47b 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -499,7 +499,7 @@ flex-direction: column; } - .attachments { + .media-upload-wrapper .attachments { padding: 0 0.5em; .attachment { From cecf3d4f8999d247378bfb4ee444348d5d4eba0a Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Sun, 28 Jun 2020 13:03:25 +0300 Subject: [PATCH 04/12] remove unnecessary type=button --- src/components/post_status_form/post_status_form.vue | 1 - 1 file changed, 1 deletion(-) diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 31fac47b..f1455cfd 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -19,7 +19,6 @@ {{ $t('status.preview') }} From 6e2de2036755287de0a6123236644842a91b9fea Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Sun, 28 Jun 2020 13:17:04 +0300 Subject: [PATCH 05/12] show preview with plaintext too --- src/components/post_status_form/post_status_form.vue | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index f1455cfd..0bee8bb5 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -17,14 +17,14 @@ />
{{ $t('status.preview') }}
From 0287d5c07e28f54be09825dcc5280dbef1c740c2 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Sun, 28 Jun 2020 13:29:07 +0300 Subject: [PATCH 06/12] update changelog with status previews --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 887588f3..feaa354d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -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 - 'Bot' settings option and badge - Added profile meta data fields that can be set in profile settings +- Added status preview option to preview your statuses before posting ### Changed - Registration page no longer requires email if the server is configured not to require it From 3c47036101c4767b4e2fb316d9ea35535197af79 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Sun, 28 Jun 2020 15:14:01 +0300 Subject: [PATCH 07/12] add automatic updating --- .../post_status_form/post_status_form.js | 14 +++++++++++++- .../post_status_form/post_status_form.vue | 7 ------- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 3f7e36a6..75b02ffb 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -6,7 +6,7 @@ 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' +import { reject, map, uniqBy, debounce } from 'lodash' import suggestor from '../emoji_input/suggestor.js' import { mapGetters } from 'vuex' import Checkbox from '../checkbox/checkbox.vue' @@ -228,6 +228,7 @@ const PostStatusForm = { el.style.height = 'auto' el.style.height = undefined this.error = null + this.closePreview() } else { this.error = data.error } @@ -262,16 +263,25 @@ const PostStatusForm = { this.previewLoading = false }) }, + debouncePreviewStatus: debounce(function (newStatus) { + this.previewStatus(newStatus) + }, 750), + autoPreview () { + this.previewLoading = true + this.debouncePreviewStatus(this.newStatus) + }, closePreview () { this.preview = null this.previewLoading = false }, addMediaFile (fileInfo) { this.newStatus.files.push(fileInfo) + this.autoPreview() }, removeMediaFile (fileInfo) { let index = this.newStatus.files.indexOf(fileInfo) this.newStatus.files.splice(index, 1) + this.autoPreview() }, uploadFailed (errString, templateArgs) { templateArgs = templateArgs || {} @@ -287,6 +297,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 @@ -321,6 +332,7 @@ const PostStatusForm = { } }, onEmojiInputInput (e) { + this.autoPreview() this.$nextTick(() => { this.resize(this.$refs['textarea']) }) diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 0bee8bb5..31a4b388 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -35,13 +35,6 @@ v-if="previewLoading" class="icon-spin3 animate-spin" /> - - {{ $t('status.preview_update') }} - Date: Sun, 28 Jun 2020 15:43:08 +0300 Subject: [PATCH 08/12] make line sizes match for errors/loading and statuses, make X hitbox bigger, remove attachments, add shorter custom message for empty status preview. fix auto update triggering --- .../post_status_form/post_status_form.js | 23 +++++++++++-------- .../post_status_form/post_status_form.vue | 16 +++++-------- src/i18n/en.json | 2 +- 3 files changed, 21 insertions(+), 20 deletions(-) diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 75b02ffb..bb5dbf97 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -170,6 +170,9 @@ const PostStatusForm = { showPreview () { return !!this.preview || this.previewLoading }, + emptyStatus () { + return this.newStatus.status === '' && this.newStatus.files.length === 0 + }, ...mapGetters(['mergedConfig']) }, watch: { @@ -185,12 +188,9 @@ const PostStatusForm = { 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 = 'Cannot post an empty status with no files' + return } const poll = this.pollFormVisible ? this.newStatus.poll : {} @@ -236,13 +236,19 @@ const PostStatusForm = { }) }, previewStatus (newStatus) { + if (this.emptyStatus) { + this.preview = { error: this.$t('status.preview_empty') } + this.previewLoading = false + return + } + this.previewLoading = true statusPoster.postStatus({ status: newStatus.status, spoilerText: newStatus.spoilerText || null, visibility: newStatus.visibility, sensitive: newStatus.nsfw, - media: newStatus.files, + media: [], store: this.$store, inReplyToStatusId: this.replyTo, contentType: newStatus.contentType, @@ -267,6 +273,7 @@ const PostStatusForm = { this.previewStatus(newStatus) }, 750), autoPreview () { + if (!this.preview) return this.previewLoading = true this.debouncePreviewStatus(this.newStatus) }, @@ -276,12 +283,10 @@ const PostStatusForm = { }, addMediaFile (fileInfo) { this.newStatus.files.push(fileInfo) - this.autoPreview() }, removeMediaFile (fileInfo) { let index = this.newStatus.files.indexOf(fileInfo) this.newStatus.files.splice(index, 1) - this.autoPreview() }, uploadFailed (errString, templateArgs) { templateArgs = templateArgs || {} diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 31a4b388..8201911e 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -35,12 +35,10 @@ v-if="previewLoading" class="icon-spin3 animate-spin" /> - - - + />
Date: Sun, 28 Jun 2020 16:40:39 +0300 Subject: [PATCH 09/12] remove panel-footer in userpanel, simplify preview header, fix word-wrap in preview --- .../post_status_form/post_status_form.js | 17 +++-- .../post_status_form/post_status_form.vue | 74 +++++++++---------- src/components/status/status.vue | 3 - .../status_content/status_content.vue | 3 + src/components/user_panel/user_panel.vue | 4 +- src/i18n/en.json | 1 - 6 files changed, 51 insertions(+), 51 deletions(-) diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index bb5dbf97..732691e7 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -235,13 +235,13 @@ const PostStatusForm = { this.posting = false }) }, - previewStatus (newStatus) { + previewStatus () { if (this.emptyStatus) { this.preview = { error: this.$t('status.preview_empty') } this.previewLoading = false return } - + const newStatus = this.newStatus this.previewLoading = true statusPoster.postStatus({ status: newStatus.status, @@ -269,18 +269,23 @@ const PostStatusForm = { this.previewLoading = false }) }, - debouncePreviewStatus: debounce(function (newStatus) { - this.previewStatus(newStatus) - }, 750), + debouncePreviewStatus: debounce(function () { this.previewStatus() }, 750), autoPreview () { if (!this.preview) return this.previewLoading = true - this.debouncePreviewStatus(this.newStatus) + 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) }, diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 8201911e..0cebd36e 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -16,30 +16,26 @@ @drop.stop="fileDrop" />
- - {{ $t('status.preview') }} - +
- - - {{ $t('status.status_preview') }} - - - -
- +
Date: Mon, 6 Jul 2020 10:53:03 +0300 Subject: [PATCH 10/12] move translation strings to correct place, translate error message --- src/components/post_status_form/post_status_form.js | 4 ++-- src/components/post_status_form/post_status_form.vue | 2 +- src/i18n/en.json | 5 +++-- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 1bf5dae3..18661235 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -192,7 +192,7 @@ const PostStatusForm = { if (this.posting) { return } if (this.submitDisabled) { return } if (this.emptyStatus) { - this.error = 'Cannot post an empty status with no files' + this.error = this.$t('post_status.empty_status_error') return } @@ -240,7 +240,7 @@ const PostStatusForm = { }, previewStatus () { if (this.emptyStatus && this.newStatus.spoilerText.trim() === '') { - this.preview = { error: this.$t('status.preview_empty') } + this.preview = { error: this.$t('post_status.preview_empty') } this.previewLoading = false return } diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 0cebd36e..94729f75 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -21,7 +21,7 @@ class="preview-toggle faint" @click.stop.prevent="togglePreview" > - {{ $t('status.preview') }} + {{ $t('post_status.preview') }} Date: Mon, 6 Jul 2020 11:12:33 +0300 Subject: [PATCH 11/12] remove contenttype check from content type watcher --- src/components/post_status_form/post_status_form.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 18661235..3d731ae4 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -176,12 +176,8 @@ const PostStatusForm = { ...mapGetters(['mergedConfig']) }, watch: { - 'newStatus.contentType': function (newType) { - if (newType === 'text/plain') { - this.closePreview() - } else if (this.preview) { - this.previewStatus(this.newStatus) - } + 'newStatus.contentType': function () { + this.autoPreview() }, 'newStatus.spoilerText': function () { this.autoPreview() From ada5a3806b3c36ad67d3a76f41bc1a9f18445759 Mon Sep 17 00:00:00 2001 From: Shpuld Shpuldson Date: Mon, 6 Jul 2020 11:36:35 +0300 Subject: [PATCH 12/12] don't close preview on post, move visibility notices above the preview where they belong --- .../post_status_form/post_status_form.js | 2 +- .../post_status_form/post_status_form.vue | 76 +++++++++---------- 2 files changed, 39 insertions(+), 39 deletions(-) diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 3d731ae4..daadc10f 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -227,7 +227,7 @@ const PostStatusForm = { el.style.height = 'auto' el.style.height = undefined this.error = null - this.closePreview() + this.previewStatus() } else { this.error = data.error } diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 94729f75..60dc4a21 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -16,44 +16,6 @@ @drop.stop="fileDrop" />
- -
-
- {{ $t('general.loading') }} -
-
- {{ preview.error }} -
- -
{{ $t('post_status.direct_warning_to_first_only') }} {{ $t('post_status.direct_warning_to_all') }}

+ +
+
+ {{ $t('general.loading') }} +
+
+ {{ preview.error }} +
+ +