Improve the public hashtag page (#9831)

- Fix height not updating when clicking show more on public hashtag page
- Add header to the public hashtag page
- Change text size and margins on the public hashtag page
This commit is contained in:
Eugen Rochko 2019-01-17 14:06:08 +01:00 committed by GitHub
parent 30af4ee65f
commit 8b19903559
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 60 additions and 41 deletions

View File

@ -4,5 +4,9 @@ export function start() {
require('font-awesome/css/font-awesome.css'); require('font-awesome/css/font-awesome.css');
require.context('../images/', true); require.context('../images/', true);
Rails.start(); try {
Rails.start();
} catch (e) {
// If called twice
}
}; };

View File

@ -80,7 +80,7 @@ class HashtagTimeline extends React.PureComponent {
<div className='statuses-grid__item' key={statusId}> <div className='statuses-grid__item' key={statusId}>
<DetailedStatusContainer <DetailedStatusContainer
id={statusId} id={statusId}
showThread compact
measureHeight measureHeight
onHeightChange={this.handleHeightChange} onHeightChange={this.handleHeightChange}
/> />

View File

@ -12,6 +12,7 @@ import Card from './card';
import ImmutablePureComponent from 'react-immutable-pure-component'; import ImmutablePureComponent from 'react-immutable-pure-component';
import Video from '../../video'; import Video from '../../video';
import scheduleIdleTask from '../../ui/util/schedule_idle_task'; import scheduleIdleTask from '../../ui/util/schedule_idle_task';
import classNames from 'classnames';
export default class DetailedStatus extends ImmutablePureComponent { export default class DetailedStatus extends ImmutablePureComponent {
@ -27,6 +28,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
measureHeight: PropTypes.bool, measureHeight: PropTypes.bool,
onHeightChange: PropTypes.func, onHeightChange: PropTypes.func,
domain: PropTypes.string.isRequired, domain: PropTypes.string.isRequired,
compact: PropTypes.bool,
}; };
state = { state = {
@ -52,7 +54,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
_measureHeight (heightJustChanged) { _measureHeight (heightJustChanged) {
if (this.props.measureHeight && this.node) { if (this.props.measureHeight && this.node) {
scheduleIdleTask(() => this.node && this.setState({ height: this.node.offsetHeight })); scheduleIdleTask(() => this.node && this.setState({ height: this.node.scrollHeight }));
if (this.props.onHeightChange && heightJustChanged) { if (this.props.onHeightChange && heightJustChanged) {
this.props.onHeightChange(); this.props.onHeightChange();
@ -86,6 +88,7 @@ export default class DetailedStatus extends ImmutablePureComponent {
render () { render () {
const status = this.props.status.get('reblog') ? this.props.status.get('reblog') : this.props.status; const status = this.props.status.get('reblog') ? this.props.status.get('reblog') : this.props.status;
const outerStyle = { boxSizing: 'border-box' }; const outerStyle = { boxSizing: 'border-box' };
const { compact } = this.props;
if (!status) { if (!status) {
return null; return null;
@ -187,20 +190,22 @@ export default class DetailedStatus extends ImmutablePureComponent {
} }
return ( return (
<div ref={this.setRef} className='detailed-status' style={outerStyle}> <div style={outerStyle}>
<a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name'> <div ref={this.setRef} className={classNames('detailed-status', { compact })}>
<div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={48} /></div> <a href={status.getIn(['account', 'url'])} onClick={this.handleAccountClick} className='detailed-status__display-name'>
<DisplayName account={status.get('account')} localDomain={this.props.domain} /> <div className='detailed-status__display-avatar'><Avatar account={status.get('account')} size={48} /></div>
</a> <DisplayName account={status.get('account')} localDomain={this.props.domain} />
</a>
<StatusContent status={status} expanded={!status.get('hidden')} onExpandedToggle={this.handleExpandedToggle} /> <StatusContent status={status} expanded={!status.get('hidden')} onExpandedToggle={this.handleExpandedToggle} />
{media} {media}
<div className='detailed-status__meta'> <div className='detailed-status__meta'>
<a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener'> <a className='detailed-status__datetime' href={status.get('url')} target='_blank' rel='noopener'>
<FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' /> <FormattedDate value={new Date(status.get('created_at'))} hour12={false} year='numeric' month='short' day='2-digit' hour='2-digit' minute='2-digit' />
</a>{applicationLink} · {reblogLink} · {favouriteLink} </a>{applicationLink} · {reblogLink} · {favouriteLink}
</div>
</div> </div>
</div> </div>
); );

View File

@ -101,6 +101,7 @@ const makeMapStateToProps = () => {
ancestorsIds, ancestorsIds,
descendantsIds, descendantsIds,
askReplyConfirmation: state.getIn(['compose', 'text']).trim().length !== 0, askReplyConfirmation: state.getIn(['compose', 'text']).trim().length !== 0,
domain: state.getIn(['meta', 'domain']),
}; };
}; };
@ -123,6 +124,7 @@ class Status extends ImmutablePureComponent {
descendantsIds: ImmutablePropTypes.list, descendantsIds: ImmutablePropTypes.list,
intl: PropTypes.object.isRequired, intl: PropTypes.object.isRequired,
askReplyConfirmation: PropTypes.bool, askReplyConfirmation: PropTypes.bool,
domain: PropTypes.string.isRequired,
}; };
state = { state = {
@ -387,7 +389,7 @@ class Status extends ImmutablePureComponent {
render () { render () {
let ancestors, descendants; let ancestors, descendants;
const { shouldUpdateScroll, status, ancestorsIds, descendantsIds, intl } = this.props; const { shouldUpdateScroll, status, ancestorsIds, descendantsIds, intl, domain } = this.props;
const { fullscreen } = this.state; const { fullscreen } = this.state;
if (status === null) { if (status === null) {
@ -438,6 +440,7 @@ class Status extends ImmutablePureComponent {
onOpenVideo={this.handleOpenVideo} onOpenVideo={this.handleOpenVideo}
onOpenMedia={this.handleOpenMedia} onOpenMedia={this.handleOpenMedia}
onToggleHidden={this.handleToggleHidden} onToggleHidden={this.handleToggleHidden}
domain={domain}
/> />
<ActionBar <ActionBar

View File

@ -450,5 +450,33 @@ $fluid-breakpoint: $maximum-width + 20px;
@media screen and (max-width: $no-gap-breakpoint) { @media screen and (max-width: $no-gap-breakpoint) {
border-bottom: 1px solid lighten($ui-base-color, 12%); border-bottom: 1px solid lighten($ui-base-color, 12%);
} }
&.compact {
.detailed-status__meta {
margin-top: 15px;
}
.status__content {
font-size: 15px;
line-height: 20px;
.emojione {
width: 20px;
height: 20px;
margin: -3px 0 0;
}
.status__content__spoiler-link {
line-height: 20px;
margin: 0;
}
}
.media-gallery,
.status-card,
.video-player {
margin-top: 15px;
}
}
} }
} }

View File

@ -1,25 +0,0 @@
.features-list
.features-list__row
.text
%h6= t 'about.features.real_conversation_title'
= t 'about.features.real_conversation_body'
.visual
= fa_icon 'fw comments'
.features-list__row
.text
%h6= t 'about.features.not_a_product_title'
= t 'about.features.not_a_product_body'
.visual
= fa_icon 'fw users'
.features-list__row
.text
%h6= t 'about.features.within_reach_title'
= t 'about.features.within_reach_body'
.visual
= fa_icon 'fw mobile'
.features-list__row
.text
%h6= t 'about.features.humane_approach_title'
= t 'about.features.humane_approach_body'
.visual
= fa_icon 'fw leaf'

View File

@ -8,5 +8,9 @@
= javascript_pack_tag 'about', integrity: true, crossorigin: 'anonymous' = javascript_pack_tag 'about', integrity: true, crossorigin: 'anonymous'
= render 'og' = render 'og'
#mastodon-timeline{ data: { props: Oj.dump(default_props.merge(hashtag: @tag.name)) } } .page-header
%h1= "##{@tag.name}"
%p= t('about.about_hashtag_html', hashtag: @tag.name)
#mastodon-timeline{ data: { props: Oj.dump(default_props.merge(hashtag: @tag.name)) }}
#modal-container #modal-container