From bbab1b1dc686103cc1ffbb3efd24b4a91ae7969d Mon Sep 17 00:00:00 2001 From: dave Date: Thu, 28 Feb 2019 21:03:35 -0500 Subject: #346: Hyperlink is not included --- src/components/post_status_form/post_status_form.vue | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/components/post_status_form') diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 5085570b..40d24b97 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -30,7 +30,9 @@ @drop="fileDrop" @dragover.prevent="fileDrag" @input="resize" - @paste="paste"> + @paste="paste" + :disabled="posting" + >
-- cgit v1.2.3-70-g09d2 From 292cdfb24b2d42d38728e8ff9ab16e2ad9e66410 Mon Sep 17 00:00:00 2001 From: Edijs Date: Wed, 6 Mar 2019 20:13:04 -0800 Subject: Merge content types translations --- src/components/post_status_form/post_status_form.js | 3 +++ src/components/post_status_form/post_status_form.vue | 6 +++--- src/components/settings/settings.vue | 2 +- src/i18n/en.json | 10 +++------- src/i18n/eo.json | 1 - src/i18n/es.json | 1 - src/i18n/ja.json | 1 - src/i18n/oc.json | 1 - src/i18n/pt.json | 1 - 9 files changed, 10 insertions(+), 16 deletions(-) (limited to 'src/components/post_status_form') diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index c28c51bf..23a2c7e2 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -171,6 +171,9 @@ const PostStatusForm = { }, formattingOptionsEnabled () { return this.$store.state.instance.formattingOptionsEnabled + }, + postFormats () { + return this.$store.state.instance.postFormats || [] } }, methods: { diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index 5085570b..93f78f65 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -36,9 +36,9 @@ diff --git a/src/components/settings/settings.vue b/src/components/settings/settings.vue index c0cfe1ab..d2346747 100644 --- a/src/components/settings/settings.vue +++ b/src/components/settings/settings.vue @@ -106,7 +106,7 @@
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js index 8586f993..a15cecaf 100644 --- a/src/services/api/api.service.js +++ b/src/services/api/api.service.js @@ -9,10 +9,8 @@ const FAVORITE_URL = '/api/favorites/create' const UNFAVORITE_URL = '/api/favorites/destroy' const RETWEET_URL = '/api/statuses/retweet' const UNRETWEET_URL = '/api/statuses/unretweet' -const STATUS_UPDATE_URL = '/api/statuses/update.json' const STATUS_DELETE_URL = '/api/statuses/destroy' const STATUS_URL = '/api/statuses/show' -const MEDIA_UPLOAD_URL = '/api/statusnet/media/upload' const CONVERSATION_URL = '/api/statusnet/conversation' const MENTIONS_URL = '/api/statuses/mentions.json' const DM_TIMELINE_URL = '/api/statuses/dm_timeline.json' @@ -46,6 +44,8 @@ const MASTODON_BLOCK_USER_URL = id => `/api/v1/accounts/${id}/block` const MASTODON_UNBLOCK_USER_URL = id => `/api/v1/accounts/${id}/unblock` const MASTODON_MUTE_USER_URL = id => `/api/v1/accounts/${id}/mute` const MASTODON_UNMUTE_USER_URL = id => `/api/v1/accounts/${id}/unmute` +const MASTODON_POST_STATUS_URL = '/api/v1/statuses' +const MASTODON_MEDIA_UPLOAD_URL = '/api/v1/media' import { each, map } from 'lodash' import { parseStatus, parseUser, parseNotification } from '../entity_normalizer/entity_normalizer.service.js' @@ -439,23 +439,25 @@ const unretweet = ({ id, credentials }) => { }) } -const postStatus = ({credentials, status, spoilerText, visibility, sensitive, mediaIds, inReplyToStatusId, contentType, noAttachmentLinks}) => { - const idsText = mediaIds.join(',') +const postStatus = ({credentials, status, spoilerText, visibility, sensitive, mediaIds, inReplyToStatusId, contentType}) => { const form = new FormData() form.append('status', status) form.append('source', 'Pleroma FE') - if (noAttachmentLinks) form.append('no_attachment_links', noAttachmentLinks) if (spoilerText) form.append('spoiler_text', spoilerText) if (visibility) form.append('visibility', visibility) if (sensitive) form.append('sensitive', sensitive) if (contentType) form.append('content_type', contentType) - form.append('media_ids', idsText) + if (mediaIds) { + mediaIds.forEach(val => { + form.append('media_ids[]', val) + }) + } if (inReplyToStatusId) { - form.append('in_reply_to_status_id', inReplyToStatusId) + form.append('in_reply_to_id', inReplyToStatusId) } - return fetch(STATUS_UPDATE_URL, { + return fetch(MASTODON_POST_STATUS_URL, { body: form, method: 'POST', headers: authHeaders(credentials) @@ -480,13 +482,12 @@ const deleteStatus = ({ id, credentials }) => { } const uploadMedia = ({formData, credentials}) => { - return fetch(MEDIA_UPLOAD_URL, { + return fetch(MASTODON_MEDIA_UPLOAD_URL, { body: formData, method: 'POST', headers: authHeaders(credentials) }) - .then((response) => response.text()) - .then((text) => (new DOMParser()).parseFromString(text, 'application/xml')) + .then((response) => response.json()) } const followImport = ({params, credentials}) => { diff --git a/src/services/status_poster/status_poster.service.js b/src/services/status_poster/status_poster.service.js index f1932bb6..e70b0f26 100644 --- a/src/services/status_poster/status_poster.service.js +++ b/src/services/status_poster/status_poster.service.js @@ -4,7 +4,7 @@ import apiService from '../api/api.service.js' const postStatus = ({ store, status, spoilerText, visibility, sensitive, media = [], inReplyToStatusId = undefined, contentType = 'text/plain' }) => { const mediaIds = map(media, 'id') - return apiService.postStatus({credentials: store.state.users.currentUser.credentials, status, spoilerText, visibility, sensitive, mediaIds, inReplyToStatusId, contentType, noAttachmentLinks: store.state.instance.noAttachmentLinks}) + return apiService.postStatus({credentials: store.state.users.currentUser.credentials, status, spoilerText, visibility, sensitive, mediaIds, inReplyToStatusId, contentType}) .then((data) => { if (!data.error) { store.dispatch('addNewStatuses', { @@ -26,25 +26,7 @@ const postStatus = ({ store, status, spoilerText, visibility, sensitive, media = const uploadMedia = ({ store, formData }) => { const credentials = store.state.users.currentUser.credentials - return apiService.uploadMedia({ credentials, formData }).then((xml) => { - // Firefox and Chrome treat method differently... - let link = xml.getElementsByTagName('link') - - if (link.length === 0) { - link = xml.getElementsByTagName('atom:link') - } - - link = link[0] - - const mediaData = { - id: xml.getElementsByTagName('media_id')[0].textContent, - url: xml.getElementsByTagName('media_url')[0].textContent, - image: link.getAttribute('href'), - mimetype: link.getAttribute('type') - } - - return mediaData - }) + return apiService.uploadMedia({ credentials, formData }) } const statusPosterService = { -- cgit v1.2.3-70-g09d2 From 909c315a44a5c6272f000325e5e9c8b33e75f873 Mon Sep 17 00:00:00 2001 From: taehoon Date: Sun, 17 Mar 2019 23:23:59 -0400 Subject: Get correct mimetype through entity_normalizer --- src/components/post_status_form/post_status_form.js | 2 +- src/services/entity_normalizer/entity_normalizer.service.js | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) (limited to 'src/components/post_status_form') diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index 142d9d90..1f0df35a 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -292,7 +292,7 @@ const PostStatusForm = { this.submitDisabled = false }, type (fileInfo) { - return fileTypeService.fileType(fileInfo.pleroma.mime_type) + return fileTypeService.fileType(fileInfo.mimetype) }, paste (e) { if (e.clipboardData.files.length > 0) { diff --git a/src/services/entity_normalizer/entity_normalizer.service.js b/src/services/entity_normalizer/entity_normalizer.service.js index 57a6adf9..0d653207 100644 --- a/src/services/entity_normalizer/entity_normalizer.service.js +++ b/src/services/entity_normalizer/entity_normalizer.service.js @@ -128,13 +128,12 @@ export const parseUser = (data) => { return output } -const parseAttachment = (data) => { +export const parseAttachment = (data) => { const output = {} const masto = !data.hasOwnProperty('oembed') if (masto) { - // Not exactly same... - output.mimetype = data.type + output.mimetype = data.pleroma.mime_type output.meta = data.meta // not present in BE yet } else { output.mimetype = data.mimetype -- cgit v1.2.3-70-g09d2 From b97a03383990d54573bd5e68393a1ad11e33608b Mon Sep 17 00:00:00 2001 From: jared Date: Mon, 25 Mar 2019 22:38:15 -0400 Subject: #255 - add emoji input component --- src/components/emoji-input/emoji-input.js | 106 +++++++++++++++++++++ src/components/emoji-input/emoji-input.vue | 99 +++++++++++++++++++ .../post_status_form/post_status_form.js | 4 +- .../post_status_form/post_status_form.vue | 5 +- 4 files changed, 211 insertions(+), 3 deletions(-) create mode 100644 src/components/emoji-input/emoji-input.js create mode 100644 src/components/emoji-input/emoji-input.vue (limited to 'src/components/post_status_form') diff --git a/src/components/emoji-input/emoji-input.js b/src/components/emoji-input/emoji-input.js new file mode 100644 index 00000000..56414358 --- /dev/null +++ b/src/components/emoji-input/emoji-input.js @@ -0,0 +1,106 @@ +import Completion from '../../services/completion/completion.js' +import { take, filter, map } from 'lodash' + +const EmojiInput = { + props: [ + 'value', + 'placeholder', + 'type' + ], + data () { + return { + highlighted: 0, + caret: 0 + } + }, + computed: { + suggestions () { + const firstchar = this.textAtCaret.charAt(0) + if (firstchar === ':') { + if (this.textAtCaret === ':') { return } + const matchedEmoji = filter(this.emoji.concat(this.customEmoji), (emoji) => emoji.shortcode.startsWith(this.textAtCaret.slice(1))) + if (matchedEmoji.length <= 0) { + return false + } + return map(take(matchedEmoji, 5), ({shortcode, image_url, utf}, index) => ({ + shortcode: `:${shortcode}:`, + utf: utf || '', + // eslint-disable-next-line camelcase + img: utf ? '' : this.$store.state.instance.server + image_url, + highlighted: index === this.highlighted + })) + } else { + return false + } + }, + textAtCaret () { + return (this.wordAtCaret || {}).word || '' + }, + wordAtCaret () { + const word = Completion.wordAtPosition(this.value, this.caret - 1) || {} + return word + }, + emoji () { + return this.$store.state.instance.emoji || [] + }, + customEmoji () { + return this.$store.state.instance.customEmoji || [] + } + }, + methods: { + replace (replacement) { + const newValue = Completion.replaceWord(this.value, this.wordAtCaret, replacement) + this.$emit('input', newValue) + this.caret = 0 + }, + replaceEmoji (e) { + const len = this.suggestions.length || 0 + if (this.textAtCaret === ':' || e.ctrlKey) { return } + if (len > 0) { + e.preventDefault() + const emoji = this.suggestions[this.highlighted] + const replacement = emoji.utf || (emoji.shortcode + ' ') + const newValue = Completion.replaceWord(this.value, this.wordAtCaret, replacement) + this.$emit('input', newValue) + this.caret = 0 + this.highlighted = 0 + } + }, + cycleBackward (e) { + const len = this.suggestions.length || 0 + if (len > 0) { + e.preventDefault() + this.highlighted -= 1 + if (this.highlighted < 0) { + this.highlighted = this.suggestions.length - 1 + } + } else { + this.highlighted = 0 + } + }, + cycleForward (e) { + const len = this.suggestions.length || 0 + if (len > 0) { + if (e.shiftKey) { return } + e.preventDefault() + this.highlighted += 1 + if (this.highlighted >= len) { + this.highlighted = 0 + } + } else { + this.highlighted = 0 + } + }, + onKeydown (e) { + e.stopPropagation() + }, + onInput (e) { + this.$emit('input', e.target.value) + }, + setCaret ({target: {selectionStart}}) { + this.caret = selectionStart + } + } +} + +export default EmojiInput diff --git a/src/components/emoji-input/emoji-input.vue b/src/components/emoji-input/emoji-input.vue new file mode 100644 index 00000000..95606305 --- /dev/null +++ b/src/components/emoji-input/emoji-input.vue @@ -0,0 +1,99 @@ + + + + + diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js index c5f30ca6..229aefb7 100644 --- a/src/components/post_status_form/post_status_form.js +++ b/src/components/post_status_form/post_status_form.js @@ -1,5 +1,6 @@ import statusPoster from '../../services/status_poster/status_poster.service.js' import MediaUpload from '../media_upload/media_upload.vue' +import EmojiInput from '../emoji-input/emoji-input.vue' import fileTypeService from '../../services/file_type/file_type.service.js' import Completion from '../../services/completion/completion.js' import { take, filter, reject, map, uniqBy } from 'lodash' @@ -28,7 +29,8 @@ const PostStatusForm = { 'subject' ], components: { - MediaUpload + MediaUpload, + EmojiInput }, mounted () { 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 612f87c1..9d449b74 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -10,12 +10,13 @@ {{ $t('post_status.account_not_locked_warning_link') }}

{{ $t('post_status.direct_warning') }}

- + class="form-cw" + />
+

-- cgit v1.2.3-70-g09d2 From 8fe9101f0b134978212bf05ed6e73894f47c617e Mon Sep 17 00:00:00 2001 From: jared Date: Tue, 26 Mar 2019 14:53:27 -0400 Subject: #255 - clean up autocomplete form --- src/App.scss | 51 +++++++++++++++++ src/components/emoji-input/emoji-input.vue | 51 ----------------- .../post_status_form/post_status_form.vue | 65 ++++------------------ 3 files changed, 63 insertions(+), 104 deletions(-) (limited to 'src/components/post_status_form') diff --git a/src/App.scss b/src/App.scss index 244b3474..ae068e4f 100644 --- a/src/App.scss +++ b/src/App.scss @@ -767,3 +767,54 @@ nav { .btn.btn-default { min-height: 28px; } + +.autocomplete { + &-panel { + position: relative; + + &-body { + margin: 0 0.5em 0 0.5em; + border-radius: $fallback--tooltipRadius; + border-radius: var(--tooltipRadius, $fallback--tooltipRadius); + position: absolute; + z-index: 1; + box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.5); + // this doesn't match original but i don't care, making it uniform. + box-shadow: var(--popupShadow); + min-width: 75%; + background: $fallback--bg; + background: var(--bg, $fallback--bg); + color: $fallback--lightText; + color: var(--lightText, $fallback--lightText); + } + } + + &-item { + cursor: pointer; + padding: 0.2em 0.4em 0.2em 0.4em; + border-bottom: 1px solid rgba(0, 0, 0, 0.4); + display: flex; + + img { + width: 24px; + height: 24px; + object-fit: contain; + } + + span { + line-height: 24px; + margin: 0 0.1em 0 0.2em; + } + + small { + margin-left: .5em; + color: $fallback--faint; + color: var(--faint, $fallback--faint); + } + + &.highlighted { + background-color: $fallback--fg; + background-color: var(--lightBg, $fallback--fg); + } + } +} \ No newline at end of file diff --git a/src/components/emoji-input/emoji-input.vue b/src/components/emoji-input/emoji-input.vue index 568bd080..338b77cd 100644 --- a/src/components/emoji-input/emoji-input.vue +++ b/src/components/emoji-input/emoji-input.vue @@ -61,55 +61,4 @@ width: 100%; } } - -.autocomplete { - &-panel { - position: relative; - - &-body { - margin: 0 0.5em 0 0.5em; - border-radius: $fallback--tooltipRadius; - border-radius: var(--tooltipRadius, $fallback--tooltipRadius); - position: absolute; - z-index: 1; - box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.5); - // this doesn't match original but i don't care, making it uniform. - box-shadow: var(--popupShadow); - min-width: 75%; - background: $fallback--bg; - background: var(--bg, $fallback--bg); - color: $fallback--lightText; - color: var(--lightText, $fallback--lightText); - } - } - - &-item { - cursor: pointer; - padding: 0.2em 0.4em 0.2em 0.4em; - border-bottom: 1px solid rgba(0, 0, 0, 0.4); - display: flex; - - img { - width: 24px; - height: 24px; - object-fit: contain; - } - - span { - line-height: 24px; - margin: 0 0.1em 0 0.2em; - } - - small { - margin-left: .5em; - color: $fallback--faint; - color: var(--faint, $fallback--faint); - } - - &.highlighted { - background-color: $fallback--fg; - background-color: var(--lightBg, $fallback--fg); - } - } -} diff --git a/src/components/post_status_form/post_status_form.vue b/src/components/post_status_form/post_status_form.vue index b2a1dc58..9f9f16ba 100644 --- a/src/components/post_status_form/post_status_form.vue +++ b/src/components/post_status_form/post_status_form.vue @@ -56,14 +56,18 @@

-
-
-
-
- - {{candidate.utf}} - {{candidate.screen_name}}{{candidate.name}} -
+
+
+
+ + {{candidate.utf}} + {{candidate.screen_name}}{{candidate.name}}
@@ -262,50 +266,5 @@ cursor: pointer; z-index: 4; } - - .autocomplete-panel { - margin: 0 0.5em 0 0.5em; - border-radius: $fallback--tooltipRadius; - border-radius: var(--tooltipRadius, $fallback--tooltipRadius); - position: absolute; - z-index: 1; - box-shadow: 1px 2px 4px rgba(0, 0, 0, 0.5); - // this doesn't match original but i don't care, making it uniform. - box-shadow: var(--popupShadow); - min-width: 75%; - background: $fallback--bg; - background: var(--bg, $fallback--bg); - color: $fallback--lightText; - color: var(--lightText, $fallback--lightText); - } - - .autocomplete { - cursor: pointer; - padding: 0.2em 0.4em 0.2em 0.4em; - border-bottom: 1px solid rgba(0, 0, 0, 0.4); - display: flex; - - img { - width: 24px; - height: 24px; - object-fit: contain; - } - - span { - line-height: 24px; - margin: 0 0.1em 0 0.2em; - } - - small { - margin-left: .5em; - color: $fallback--faint; - color: var(--faint, $fallback--faint); - } - - &.highlighted { - background-color: $fallback--fg; - background-color: var(--lightBg, $fallback--fg); - } - } } -- cgit v1.2.3-70-g09d2