From 591cf4918e7277c7ebfad7295b4b5e81f1b80192 Mon Sep 17 00:00:00 2001 From: Claire Date: Sat, 21 Dec 2024 18:33:53 +0100 Subject: [PATCH] =?UTF-8?q?Use=20upstream's=20=E2=80=9CRead=20More?= =?UTF-8?q?=E2=80=9D=20implementation?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../flavours/glitch/components/status.jsx | 5 +++ .../glitch/components/status_content.jsx | 36 +++++++++++++++++-- .../glitch/containers/status_container.js | 6 ++++ .../flavours/glitch/styles/components.scss | 5 +++ 4 files changed, 49 insertions(+), 3 deletions(-) diff --git a/app/javascript/flavours/glitch/components/status.jsx b/app/javascript/flavours/glitch/components/status.jsx index f437686f3e73d1..168b5f20718873 100644 --- a/app/javascript/flavours/glitch/components/status.jsx +++ b/app/javascript/flavours/glitch/components/status.jsx @@ -100,6 +100,7 @@ class Status extends ImmutablePureComponent { onEmbed: PropTypes.func, onHeightChange: PropTypes.func, onToggleHidden: PropTypes.func, + onToggleCollapsed: PropTypes.func, onTranslate: PropTypes.func, onInteractionModal: PropTypes.func, muted: PropTypes.bool, @@ -413,6 +414,10 @@ class Status extends ImmutablePureComponent { this.node = c; }; + handleCollapsedToggle = isCollapsed => { + this.props.onToggleCollapsed(this.props.status, isCollapsed); + }; + handleTranslate = () => { this.props.onTranslate(this.props.status); }; diff --git a/app/javascript/flavours/glitch/components/status_content.jsx b/app/javascript/flavours/glitch/components/status_content.jsx index 46bca4fa917a81..63a2173a75b7be 100644 --- a/app/javascript/flavours/glitch/components/status_content.jsx +++ b/app/javascript/flavours/glitch/components/status_content.jsx @@ -9,6 +9,7 @@ import { withRouter } from 'react-router-dom'; import ImmutablePropTypes from 'react-immutable-proptypes'; import { connect } from 'react-redux'; +import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'; import ImageIcon from '@/material-icons/400-24px/image.svg?react'; import InsertChartIcon from '@/material-icons/400-24px/insert_chart.svg?react'; import LinkIcon from '@/material-icons/400-24px/link.svg?react'; @@ -22,6 +23,8 @@ import { decode as decodeIDNA } from 'flavours/glitch/utils/idna'; import { Permalink } from './permalink'; +const MAX_HEIGHT = 706; // 22px * 32 (+ 2px padding at the top) + const textMatchesTarget = (text, origin, host) => { return (text === origin || text === host || text.startsWith(origin + '/') || text.startsWith(host + '/') @@ -133,13 +136,14 @@ class StatusContent extends PureComponent { status: ImmutablePropTypes.map.isRequired, statusContent: PropTypes.string, expanded: PropTypes.bool, - collapsed: PropTypes.bool, onExpandedToggle: PropTypes.func, onTranslate: PropTypes.func, media: PropTypes.node, extraMedia: PropTypes.node, mediaIcons: PropTypes.arrayOf(PropTypes.string), onClick: PropTypes.func, + collapsible: PropTypes.bool, + onCollapsedToggle: PropTypes.func, onUpdate: PropTypes.func, tagLinks: PropTypes.bool, rewriteMentions: PropTypes.string, @@ -168,16 +172,21 @@ class StatusContent extends PureComponent { return; } + const { status, onCollapsedToggle } = this.props; const links = node.querySelectorAll('a'); + let link, mention; + for (var i = 0; i < links.length; ++i) { - let link = links[i]; + link = links[i]; + if (link.classList.contains('status-link')) { continue; } + link.classList.add('status-link'); - let mention = this.props.status.get('mentions').find(item => link.href === item.get('url')); + mention = this.props.status.get('mentions').find(item => link.href === item.get('url')); if (mention) { link.addEventListener('click', this.onMentionClick.bind(this, mention), false); @@ -225,6 +234,18 @@ class StatusContent extends PureComponent { } } } + + if (status.get('collapsed', null) === null && onCollapsedToggle) { + const { collapsible, onClick } = this.props; + + const collapsed = + collapsible + && onClick + && node.clientHeight > MAX_HEIGHT + && status.get('spoiler_text').length === 0; + + onCollapsedToggle(collapsed); + } } handleMouseEnter = ({ currentTarget }) => { @@ -335,6 +356,7 @@ class StatusContent extends PureComponent { statusContent, } = this.props; + const renderReadMore = this.props.onClick && status.get('collapsed'); const hidden = this.props.onExpandedToggle ? !this.props.expanded : this.state.hidden; const contentLocale = intl.locale.replace(/[_-].*/, ''); const targetLanguages = this.props.languages?.get(status.get('language') || 'und'); @@ -345,9 +367,16 @@ class StatusContent extends PureComponent { const language = status.getIn(['translation', 'language']) || status.get('language'); const classNames = classnames('status__content', { 'status__content--with-action': this.props.onClick && this.props.history, + 'status__content--collapsed': renderReadMore, 'status__content--with-spoiler': status.get('spoiler_text').length > 0, }); + const readMoreButton = renderReadMore && ( + + ); + const translateButton = renderTranslate && ( ); @@ -435,6 +464,7 @@ class StatusContent extends PureComponent { lang={language} /> {translateButton} + {readMoreButton} {media} {extraMedia} diff --git a/app/javascript/flavours/glitch/containers/status_container.js b/app/javascript/flavours/glitch/containers/status_container.js index 493a01da2390a0..d19cf6dd23f907 100644 --- a/app/javascript/flavours/glitch/containers/status_container.js +++ b/app/javascript/flavours/glitch/containers/status_container.js @@ -26,6 +26,7 @@ import { unmuteStatus, deleteStatus, toggleStatusSpoilers, + toggleStatusCollapse, editStatus, translateStatus, undoStatusTranslation, @@ -191,6 +192,11 @@ const mapDispatchToProps = (dispatch, { contextType }) => ({ dispatch(toggleStatusSpoilers(status.get('id'))); }, + onToggleCollapsed (status, isCollapsed) { + dispatch(toggleStatusCollapse(status.get('id'), isCollapsed)); + }, + + deployPictureInPicture (status, type, mediaProps) { dispatch((_, getState) => { if (getState().getIn(['local_settings', 'media', 'pop_in_player'])) { diff --git a/app/javascript/flavours/glitch/styles/components.scss b/app/javascript/flavours/glitch/styles/components.scss index 88f27845809344..12545c9345ec16 100644 --- a/app/javascript/flavours/glitch/styles/components.scss +++ b/app/javascript/flavours/glitch/styles/components.scss @@ -1349,6 +1349,11 @@ body > [data-popper-placement] { } } +.status__content.status__content--collapsed .status__content__text { + max-height: 22px * 15; // 15 lines is roughly above 500 characters + overflow: hidden; +} + .status__content__read-more-button, .status__content__translate-button { display: flex;