From 6d4d96528c60ee56a6cea8a158b2c6ad0d0ef4f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?marcin=20miko=C5=82ajczak?= Date: Tue, 29 Mar 2022 20:12:49 +0200 Subject: [PATCH] quote posts? MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: marcin mikołajczak --- app/soapbox/components/account.tsx | 3 +- app/soapbox/components/ui/stack/stack.tsx | 2 +- .../status/components/quoted_status.js | 162 ------------------ .../status/components/quoted_status.tsx | 155 +++++++++++++++++ 4 files changed, 158 insertions(+), 164 deletions(-) delete mode 100644 app/soapbox/features/status/components/quoted_status.js create mode 100644 app/soapbox/features/status/components/quoted_status.tsx diff --git a/app/soapbox/components/account.tsx b/app/soapbox/components/account.tsx index cd8ee546e..21178d5e4 100644 --- a/app/soapbox/components/account.tsx +++ b/app/soapbox/components/account.tsx @@ -30,9 +30,10 @@ interface IAccount { avatarSize?: number, hidden?: boolean, hideActions?: boolean, + id?: string, onActionClick?: (account: any) => void, showProfileHoverCard?: boolean, - timestamp?: string, + timestamp?: string | Date, timestampUrl?: string, withRelationship?: boolean, } diff --git a/app/soapbox/components/ui/stack/stack.tsx b/app/soapbox/components/ui/stack/stack.tsx index 46e29d0f6..1441ae17e 100644 --- a/app/soapbox/components/ui/stack/stack.tsx +++ b/app/soapbox/components/ui/stack/stack.tsx @@ -21,7 +21,7 @@ const alignItemsOptions = { center: 'items-center', }; -interface IStack { +interface IStack extends React.HTMLAttributes { space?: SIZES, alignItems?: 'center', justifyContent?: 'center', diff --git a/app/soapbox/features/status/components/quoted_status.js b/app/soapbox/features/status/components/quoted_status.js deleted file mode 100644 index c31415a02..000000000 --- a/app/soapbox/features/status/components/quoted_status.js +++ /dev/null @@ -1,162 +0,0 @@ -import PropTypes from 'prop-types'; -import React from 'react'; -import ImmutablePropTypes from 'react-immutable-proptypes'; -import ImmutablePureComponent from 'react-immutable-pure-component'; -import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; -import { NavLink, withRouter } 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 IconButton from 'soapbox/components/icon_button'; -import RelativeTimestamp from 'soapbox/components/relative_timestamp'; -import { isRtl } from 'soapbox/rtl'; - -const messages = defineMessages({ - cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' }, -}); - -export default @injectIntl @withRouter -class QuotedStatus extends ImmutablePureComponent { - - static propTypes = { - status: ImmutablePropTypes.record, - onCancel: PropTypes.func, - intl: PropTypes.object.isRequired, - compose: PropTypes.bool, - history: PropTypes.object, - }; - - handleExpandClick = e => { - const { compose, status } = this.props; - - if (!compose && e.button === 0) { - if (!this.props.history) { - return; - } - - this.props.history.push(`/@${status.getIn(['account', 'acct'])}/posts/${status.get('id')}`); - - e.preventDefault(); - } - } - - handleClose = e => { - this.props.onCancel(); - - e.preventDefault(); - } - - 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, onCancel, intl, compose } = this.props; - - if (!status) { - return null; - } - - const content = { __html: status.get('contentHtml') }; - const style = { - direction: isRtl(status.get('search_index')) ? 'rtl' : 'ltr', - }; - - const displayName = (<> -
- - ); - - const quotedStatus = ( -
-
- {onCancel - ? ( -
- -
- ) : ( -
- -
- )} - {compose ? ( -
- {displayName} -
- ) : ( - - {displayName} - - )} -
- - {this.renderReplyMentions()} - -
- - {status.get('media_attachments').size > 0 && ( - - )} -
- ); - - if (compose) { - return ( -
- {quotedStatus} -
- ); - } - - return quotedStatus; - } - -} diff --git a/app/soapbox/features/status/components/quoted_status.tsx b/app/soapbox/features/status/components/quoted_status.tsx new file mode 100644 index 000000000..25c8e850e --- /dev/null +++ b/app/soapbox/features/status/components/quoted_status.tsx @@ -0,0 +1,155 @@ +import classNames from 'classnames'; +import { History } from 'history'; +import React from 'react'; +import ImmutablePureComponent from 'react-immutable-pure-component'; +import { defineMessages, injectIntl, FormattedMessage, IntlShape } from 'react-intl'; +import { withRouter } from 'react-router-dom'; + +import AttachmentThumbs from 'soapbox/components/attachment_thumbs'; +import { Stack, Text } from 'soapbox/components/ui'; +import AccountContainer from 'soapbox/containers/account_container'; +import { Account as AccountEntity, Status as StatusEntity } from 'soapbox/types/entities'; + +const messages = defineMessages({ + cancel: { id: 'reply_indicator.cancel', defaultMessage: 'Cancel' }, +}); + +interface IQuotedStatus { + status?: StatusEntity, + onCancel?: Function, + intl: IntlShape, + compose?: boolean, + history: History, +} + +class QuotedStatus extends ImmutablePureComponent { + + handleExpandClick = (e: React.MouseEvent) => { + const { compose, status } = this.props; + + if (!status) return; + + const account = status.account as AccountEntity; + + if (!compose && e.button === 0) { + if (!this.props.history) { + return; + } + + this.props.history.push(`/@${account.acct}/posts/${status.id}`); + + e.preventDefault(); + } + } + + handleClose = () => { + if (this.props.onCancel) { + this.props.onCancel(); + } + } + + renderReplyMentions = () => { + const { status } = this.props; + + if (!status?.in_reply_to_id) { + return null; + } + + const account = status.account as AccountEntity; + + const to = status.mentions || []; + + if (to.size === 0) { + if (status.in_reply_to_account_id === account.id) { + return ( +
+ +
+ ); + } else { + return ( +
+ +
+ ); + } + } + + return ( +
+ `@${account.username} `), + more: to.size > 2 && , + }} + /> +
+ ); + } + + render() { + const { status, onCancel, intl, compose } = this.props; + + if (!status) { + return null; + } + + const account = status.account as AccountEntity; + + let actions = {}; + if (onCancel) { + actions = { + onActionClick: this.handleClose, + actionIcon: require('@tabler/icons/icons/x.svg'), + actionAlignment: 'top', + actionTitle: intl.formatMessage(messages.cancel), + }; + } + + const quotedStatus = ( + + + + {this.renderReplyMentions()} + + + + {status.media_attachments.size > 0 && ( + + )} + + ); + + return quotedStatus; + } + +} + +export default withRouter(injectIntl(QuotedStatus) as any); \ No newline at end of file