diff --git a/src/components/post_status_form/post_status_form.js b/src/components/post_status_form/post_status_form.js
index 19504169..4e59e430 100644
--- a/src/components/post_status_form/post_status_form.js
+++ b/src/components/post_status_form/post_status_form.js
@@ -56,6 +56,7 @@ const pxStringToNumber = (str) => {
const PostStatusForm = {
props: [
'replyTo',
+ 'quoteId',
'repliedUser',
'attentions',
'copyMessageScope',
@@ -99,12 +100,12 @@ const PostStatusForm = {
this.updateIdempotencyKey()
this.resize(this.$refs.textarea)
- if (this.replyTo) {
+ if (this.replyTo || this.quoteId) {
const textLength = this.$refs.textarea.value.length
this.$refs.textarea.setSelectionRange(textLength, textLength)
}
- if (this.replyTo || this.autoFocus) {
+ if (this.replyTo || this.quoteId || this.autoFocus) {
this.$refs.textarea.focus()
}
},
@@ -112,7 +113,7 @@ const PostStatusForm = {
const preset = this.$route.query.message
let statusText = preset || ''
- if (this.replyTo) {
+ if (this.replyTo || this.quoteId) {
const currentUser = this.$store.state.users.currentUser
statusText = buildMentionsString({ user: this.repliedUser, attentions: this.attentions }, currentUser)
}
@@ -314,6 +315,7 @@ const PostStatusForm = {
media: newStatus.files,
store: this.$store,
inReplyToStatusId: this.replyTo,
+ quoteId: this.quoteId,
contentType: newStatus.contentType,
poll,
idempotencyKey: this.idempotencyKey
@@ -347,6 +349,7 @@ const PostStatusForm = {
media: [],
store: this.$store,
inReplyToStatusId: this.replyTo,
+ quoteId: this.quoteId,
contentType: newStatus.contentType,
poll: {},
preview: true
diff --git a/src/components/quote_button/quote_button.js b/src/components/quote_button/quote_button.js
new file mode 100644
index 00000000..227a68e2
--- /dev/null
+++ b/src/components/quote_button/quote_button.js
@@ -0,0 +1,16 @@
+import { library } from '@fortawesome/fontawesome-svg-core'
+import { faQuoteLeft } from '@fortawesome/free-solid-svg-icons'
+
+library.add(faQuoteLeft)
+
+const QuoteButton = {
+ name: 'QuoteButton',
+ props: ['status', 'quoting'],
+ computed: {
+ loggedIn () {
+ return !!this.$store.state.users.currentUser
+ }
+ }
+}
+
+export default QuoteButton
diff --git a/src/components/quote_button/quote_button.vue b/src/components/quote_button/quote_button.vue
new file mode 100644
index 00000000..319db8b4
--- /dev/null
+++ b/src/components/quote_button/quote_button.vue
@@ -0,0 +1,52 @@
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/components/status/status.js b/src/components/status/status.js
index d1339652..dcf93688 100644
--- a/src/components/status/status.js
+++ b/src/components/status/status.js
@@ -1,4 +1,5 @@
import ReplyButton from '../reply_button/reply_button.vue'
+import QuoteButton from '../quote_button/quote_button.vue'
import FavoriteButton from '../favorite_button/favorite_button.vue'
import ReactButton from '../react_button/react_button.vue'
import RetweetButton from '../retweet_button/retweet_button.vue'
@@ -115,7 +116,8 @@ const Status = {
StatusContent,
RichContent,
MentionLink,
- MentionsLine
+ MentionsLine,
+ QuoteButton
},
props: [
'statusoid',
@@ -145,6 +147,8 @@ const Status = {
'controlledToggleShowingLongSubject',
'controlledReplying',
'controlledToggleReplying',
+ 'controlledQuoting',
+ 'controlledToggleQuoting',
'controlledMediaPlaying',
'controlledSetMediaPlaying',
'dive'
@@ -152,6 +156,7 @@ const Status = {
data () {
return {
uncontrolledReplying: false,
+ uncontrolledQuoting: false,
unmuted: false,
userExpanded: false,
uncontrolledMediaPlaying: [],
@@ -161,7 +166,7 @@ const Status = {
}
},
computed: {
- ...controlledOrUncontrolledGetters(['replying', 'mediaPlaying']),
+ ...controlledOrUncontrolledGetters(['replying', 'quoting', 'mediaPlaying']),
muteWords () {
return this.mergedConfig.muteWords
},
@@ -418,6 +423,9 @@ const Status = {
toggleReplying () {
controlledOrUncontrolledToggle(this, 'replying')
},
+ toggleQuoting () {
+ controlledOrUncontrolledToggle(this, 'quoting')
+ },
gotoOriginal (id) {
if (this.inConversation) {
this.$emit('goto', id)
diff --git a/src/components/status/status.scss b/src/components/status/status.scss
index b3ad3818..6c679fb6 100644
--- a/src/components/status/status.scss
+++ b/src/components/status/status.scss
@@ -355,6 +355,15 @@
flex: 1;
}
+ .quote-form {
+ padding-top: 0;
+ padding-bottom: 0;
+ }
+
+ .quote-body {
+ flex: 1;
+ }
+
.favs-repeated-users {
margin-top: var(--status-margin, $status-margin);
}
diff --git a/src/components/status/status.vue b/src/components/status/status.vue
index 67ce999a..f3e90dee 100644
--- a/src/components/status/status.vue
+++ b/src/components/status/status.vue
@@ -430,6 +430,11 @@
:status="status"
@toggle="toggleReplying"
/>
+
+
diff --git a/src/services/api/api.service.js b/src/services/api/api.service.js
index f00985a8..686689cd 100644
--- a/src/services/api/api.service.js
+++ b/src/services/api/api.service.js
@@ -763,6 +763,7 @@ const postStatus = ({
poll,
mediaIds = [],
inReplyToStatusId,
+ quoteId,
contentType,
preview,
idempotencyKey
@@ -795,6 +796,9 @@ const postStatus = ({
if (inReplyToStatusId) {
form.append('in_reply_to_id', inReplyToStatusId)
}
+ if (quoteId) {
+ form.append('quote_id', quoteId)
+ }
if (preview) {
form.append('preview', 'true')
}
diff --git a/src/services/status_poster/status_poster.service.js b/src/services/status_poster/status_poster.service.js
index f09196aa..d1c5db19 100644
--- a/src/services/status_poster/status_poster.service.js
+++ b/src/services/status_poster/status_poster.service.js
@@ -10,6 +10,7 @@ const postStatus = ({
poll,
media = [],
inReplyToStatusId = undefined,
+ quoteId = undefined,
contentType = 'text/plain',
preview = false,
idempotencyKey = ''
@@ -24,6 +25,7 @@ const postStatus = ({
sensitive,
mediaIds,
inReplyToStatusId,
+ quoteId,
contentType,
poll,
preview,