From 0f8ddf367c706f4dee7faf5001b83f492fd9fc73 Mon Sep 17 00:00:00 2001 From: Eugen Rochko Date: Mon, 7 Aug 2023 09:46:11 +0200 Subject: [PATCH] [Glitch] Change header of hashtag timelines in web UI Port e325443b0270edeaf159f010fb1b1078057a6017 to glitch-soc Signed-off-by: Claire --- .../components/hashtag_header.jsx | 79 +++++++++++++++++++ .../features/hashtag_timeline/index.jsx | 35 ++------ .../glitch/styles/components/columns.scss | 30 +++++++ 3 files changed, 115 insertions(+), 29 deletions(-) create mode 100644 app/javascript/flavours/glitch/features/hashtag_timeline/components/hashtag_header.jsx diff --git a/app/javascript/flavours/glitch/features/hashtag_timeline/components/hashtag_header.jsx b/app/javascript/flavours/glitch/features/hashtag_timeline/components/hashtag_header.jsx new file mode 100644 index 0000000000..986bf80b51 --- /dev/null +++ b/app/javascript/flavours/glitch/features/hashtag_timeline/components/hashtag_header.jsx @@ -0,0 +1,79 @@ +import PropTypes from 'prop-types'; + +import { defineMessages, injectIntl, FormattedMessage } from 'react-intl'; + +import ImmutablePropTypes from 'react-immutable-proptypes'; + +import Button from 'flavours/glitch/components/button'; +import { ShortNumber } from 'flavours/glitch/components/short_number'; + +const messages = defineMessages({ + followHashtag: { id: 'hashtag.follow', defaultMessage: 'Follow hashtag' }, + unfollowHashtag: { id: 'hashtag.unfollow', defaultMessage: 'Unfollow hashtag' }, +}); + +const usesRenderer = (displayNumber, pluralReady) => ( + {displayNumber}, + }} + /> +); + +const peopleRenderer = (displayNumber, pluralReady) => ( + {displayNumber}, + }} + /> +); + +const usesTodayRenderer = (displayNumber, pluralReady) => ( + {displayNumber}, + }} + /> +); + +export const HashtagHeader = injectIntl(({ tag, intl, disabled, onClick }) => { + if (!tag) { + return null; + } + + const [uses, people] = tag.get('history').reduce((arr, day) => [arr[0] + day.get('uses') * 1, arr[1] + day.get('accounts') * 1], [0, 0]); + const dividingCircle = {' ยท '}; + + return ( +
+
+

#{tag.get('name')}

+
+ +
+ + {dividingCircle} + + {dividingCircle} + +
+
+ ); +}); + +HashtagHeader.propTypes = { + tag: ImmutablePropTypes.map, + disabled: PropTypes.bool, + onClick: PropTypes.func, + intl: PropTypes.object, +}; \ No newline at end of file diff --git a/app/javascript/flavours/glitch/features/hashtag_timeline/index.jsx b/app/javascript/flavours/glitch/features/hashtag_timeline/index.jsx index de67b06ca8..af889f6d61 100644 --- a/app/javascript/flavours/glitch/features/hashtag_timeline/index.jsx +++ b/app/javascript/flavours/glitch/features/hashtag_timeline/index.jsx @@ -1,9 +1,8 @@ import PropTypes from 'prop-types'; import { PureComponent } from 'react'; -import { injectIntl, FormattedMessage, defineMessages } from 'react-intl'; +import { FormattedMessage } from 'react-intl'; -import classNames from 'classnames'; import { Helmet } from 'react-helmet'; import ImmutablePropTypes from 'react-immutable-proptypes'; @@ -17,17 +16,11 @@ import { fetchHashtag, followHashtag, unfollowHashtag } from 'flavours/glitch/ac import { expandHashtagTimeline, clearTimeline } from 'flavours/glitch/actions/timelines'; import Column from 'flavours/glitch/components/column'; import ColumnHeader from 'flavours/glitch/components/column_header'; -import { Icon } from 'flavours/glitch/components/icon'; import StatusListContainer from 'flavours/glitch/features/ui/containers/status_list_container'; +import { HashtagHeader } from './components/hashtag_header'; import ColumnSettingsContainer from './containers/column_settings_container'; - -const messages = defineMessages({ - followHashtag: { id: 'hashtag.follow', defaultMessage: 'Follow hashtag' }, - unfollowHashtag: { id: 'hashtag.unfollow', defaultMessage: 'Unfollow hashtag' }, -}); - const mapStateToProps = (state, props) => ({ hasUnread: state.getIn(['timelines', `hashtag:${props.params.id}${props.params.local ? ':local' : ''}`, 'unread']) > 0, tag: state.getIn(['tags', props.params.id]), @@ -48,7 +41,6 @@ class HashtagTimeline extends PureComponent { hasUnread: PropTypes.bool, tag: ImmutablePropTypes.map, multiColumn: PropTypes.bool, - intl: PropTypes.object, }; handlePin = () => { @@ -188,27 +180,11 @@ class HashtagTimeline extends PureComponent { }; render () { - const { hasUnread, columnId, multiColumn, tag, intl } = this.props; + const { hasUnread, columnId, multiColumn, tag } = this.props; const { id, local } = this.props.params; const pinned = !!columnId; const { signedIn } = this.context.identity; - let followButton; - - if (tag) { - const following = tag.get('following'); - - const classes = classNames('column-header__button', { - active: following, - }); - - followButton = ( - - ); - } - return ( {columnId && } } + alwaysPrepend trackScroll={!pinned} scrollKey={`hashtag_timeline-${columnId}`} timelineId={`hashtag:${id}${local ? ':local' : ''}`} @@ -245,4 +222,4 @@ class HashtagTimeline extends PureComponent { } -export default connect(mapStateToProps)(injectIntl(HashtagTimeline)); +export default connect(mapStateToProps)(HashtagTimeline); diff --git a/app/javascript/flavours/glitch/styles/components/columns.scss b/app/javascript/flavours/glitch/styles/components/columns.scss index 2ca456191c..d4860258ed 100644 --- a/app/javascript/flavours/glitch/styles/components/columns.scss +++ b/app/javascript/flavours/glitch/styles/components/columns.scss @@ -1038,3 +1038,33 @@ $ui-header-height: 55px; } } } + +.hashtag-header { + border-bottom: 1px solid lighten($ui-base-color, 8%); + padding: 15px; + font-size: 17px; + line-height: 22px; + color: $darker-text-color; + + strong { + font-weight: 700; + } + + &__header { + display: flex; + justify-content: space-between; + align-items: center; + margin-bottom: 15px; + gap: 15px; + + h1 { + color: $primary-text-color; + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + font-size: 22px; + line-height: 33px; + font-weight: 700; + } + } +}