From c0bee9be3c6c9cc2c9e095d2419e6f5822b7353b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Sun, 23 Jan 2022 17:55:03 +0100 Subject: [PATCH] Display quoted posts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- app/soapbox/actions/importer/index.js | 4 + app/soapbox/components/status.js | 8 ++ .../status/components/detailed_status.js | 8 ++ .../status/components/quoted_status.js | 132 ++++++++++++++++++ app/styles/components/status.scss | 62 ++++++++ app/styles/ui.scss | 3 +- 6 files changed, 216 insertions(+), 1 deletion(-) create mode 100644 app/soapbox/features/status/components/quoted_status.js diff --git a/app/soapbox/actions/importer/index.js b/app/soapbox/actions/importer/index.js index 407bb7c30..62e9e7860 100644 --- a/app/soapbox/actions/importer/index.js +++ b/app/soapbox/actions/importer/index.js @@ -75,6 +75,10 @@ export function importFetchedStatus(status, idempotencyKey) { dispatch(importFetchedStatus(status.reblog)); } + if (status.pleroma && status.pleroma.quote && status.pleroma.quote.id) { + dispatch(importFetchedStatus(status.pleroma.quote)); + } + if (status.poll && status.poll.id) { dispatch(importFetchedPoll(status.poll)); } diff --git a/app/soapbox/components/status.js b/app/soapbox/components/status.js index 2f5e12705..5637061e2 100644 --- a/app/soapbox/components/status.js +++ b/app/soapbox/components/status.js @@ -10,6 +10,7 @@ import { Link, NavLink } from 'react-router-dom'; import HoverRefWrapper from 'soapbox/components/hover_ref_wrapper'; import Icon from 'soapbox/components/icon'; import PlaceholderCard from 'soapbox/features/placeholder/components/placeholder_card'; +import QuotedStatus from 'soapbox/features/status/components/quoted_status'; import { getDomain } from 'soapbox/utils/accounts'; import Card from '../features/status/components/card'; @@ -472,6 +473,12 @@ class Status extends ImmutablePureComponent { ); } + let quote; + + if (status.getIn(['pleroma', 'quote'])) { + quote = ; + } + if (otherAccounts && otherAccounts.size > 1) { statusAvatar = ; } else if (account === undefined || account === null) { @@ -551,6 +558,7 @@ class Status extends ImmutablePureComponent { {media} {poll} + {quote} ; } + let quote; + + if (status.getIn(['pleroma', 'quote'])) { + quote = ; + } + if (status.get('visibility') === 'direct') { statusTypeIcon = ; } else if (status.get('visibility') === 'private') { @@ -201,6 +208,7 @@ class DetailedStatus extends ImmutablePureComponent { /> {media} + {quote}
diff --git a/app/soapbox/features/status/components/quoted_status.js b/app/soapbox/features/status/components/quoted_status.js new file mode 100644 index 000000000..c62e287f8 --- /dev/null +++ b/app/soapbox/features/status/components/quoted_status.js @@ -0,0 +1,132 @@ +import PropTypes from 'prop-types'; +import React from 'react'; +import ImmutablePropTypes from 'react-immutable-proptypes'; +import ImmutablePureComponent from 'react-immutable-pure-component'; +import { FormattedMessage, injectIntl } from 'react-intl'; +import { connect } from 'react-redux'; +import { NavLink } from 'react-router-dom'; + +import AttachmentThumbs from 'soapbox/components/attachment_thumbs'; +import Avatar from 'soapbox/components/avatar'; +import DisplayName from 'soapbox/components/display_name'; +import RelativeTimestamp from 'soapbox/components/relative_timestamp'; +import { isRtl } from 'soapbox/rtl'; +import { makeGetStatus } from 'soapbox/selectors'; + +const makeMapStateToProps = () => { + const getStatus = makeGetStatus(); + + const mapStateToProps = (state, props) => ({ + status: getStatus(state, { id: props.statusId }), + }); + + return mapStateToProps; +}; + +export default @connect(makeMapStateToProps) +@injectIntl +class QuotedStatus extends ImmutablePureComponent { + + static contextTypes = { + router: PropTypes.object, + }; + + static propTypes = { + status: ImmutablePropTypes.map, + }; + + handleExpandClick = (e) => { + if (e.button === 0) { + if (!this.context.router) { + return; + } + + this.context.router.history.push(`/@${this.props.status.getIn(['account', 'acct'])}/posts/${this.props.status.get('id')}`); + } + } + + renderReplyMentions = () => { + const { status } = this.props; + + if (!status.get('in_reply_to_id')) { + return null; + } + + const to = status.get('mentions', []); + + if (to.size === 0) { + if (status.get('in_reply_to_account_id') === status.getIn(['account', 'id'])) { + return ( +
+ +
+ ); + } else { + return ( +
+ +
+ ); + } + } + + return ( +
+ `@${account.get('username')} `), + more: to.size > 2 && , + }} + /> +
+ ); + } + + render() { + const { status } = this.props; + + if (!status) { + return null; + } + + const content = { __html: status.get('contentHtml') }; + const style = { + direction: isRtl(status.get('search_index')) ? 'rtl' : 'ltr', + }; + + return ( +
+
+
+ +
+ +
+ +
+
+ + {this.renderReplyMentions()} + +
+ + {status.get('media_attachments').size > 0 && ( + + )} +
+ ); + } + +} diff --git a/app/styles/components/status.scss b/app/styles/components/status.scss index c8fd1e55b..b3c982554 100644 --- a/app/styles/components/status.scss +++ b/app/styles/components/status.scss @@ -746,3 +746,65 @@ a.status-card.compact:hover { .pending-status { opacity: 0.5; } + +.quoted-status { + margin-top: 14px; + border: 1px solid var(--brand-color--med); + border-radius: 10px; + padding: 12px; + overflow-y: auto; + flex: 0 2 auto; + transition: background 0.2s; + cursor: pointer; + + &:hover, + &:focus, + &:active { + background: var(--brand-color--faint); + } + + &__relative-time { + padding-top: 4px; + } + + &__display-name { + color: var(--primary-text-color); + display: block; + max-width: 100%; + line-height: 24px; + overflow: hidden; + padding-right: 25px; + text-decoration: none; + + .display-name__account { + color: var(--primary-text-color--faint); + } + } + + &__display-avatar { + float: left; + margin-right: 5px; + } + + .reply-mentions { + font-size: 14px; + } + + &__content { + margin-top: 5px; + font-size: 14px; + + a { + color: var(--highlight-text-color); + text-decoration: none; + + &:hover { + text-decoration: underline; + } + } + } + + .attachment-thumbs .media-gallery { + margin-top: 5px !important; + } +} diff --git a/app/styles/ui.scss b/app/styles/ui.scss index a594752e5..de2ce5e3b 100644 --- a/app/styles/ui.scss +++ b/app/styles/ui.scss @@ -221,7 +221,8 @@ } .status__relative-time, -.notification__relative_time { +.notification__relative_time, +.quoted-status__relative-time { color: var(--primary-text-color--faint); float: right; font-size: 14px;