0
0
Fork 0

Simplify column headers (#27557)

This commit is contained in:
Renaud Chaput 2023-10-27 15:21:07 +02:00 committed by GitHub
parent 1f5187e2e2
commit 13d310e64d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 113 additions and 125 deletions

View file

@ -10,7 +10,6 @@ import { ReactComponent as BlockIcon } from '@material-symbols/svg-600/outlined/
import { debounce } from 'lodash';
import { fetchBlocks, expandBlocks } from '../../actions/blocks';
import { ColumnBackButtonSlim } from '../../components/column_back_button';
import { LoadingIndicator } from '../../components/loading_indicator';
import ScrollableList from '../../components/scrollable_list';
import AccountContainer from '../../containers/account_container';
@ -60,8 +59,7 @@ class Blocks extends ImmutablePureComponent {
const emptyMessage = <FormattedMessage id='empty_column.blocks' defaultMessage="You haven't blocked any users yet." />;
return (
<Column bindToDocument={!multiColumn} icon='ban' iconComponent={BlockIcon} heading={intl.formatMessage(messages.heading)}>
<ColumnBackButtonSlim />
<Column bindToDocument={!multiColumn} icon='ban' iconComponent={BlockIcon} heading={intl.formatMessage(messages.heading)} alwaysShowBackButton>
<ScrollableList
scrollKey='blocks'
onLoadMore={this.handleLoadMore}

View file

@ -12,7 +12,6 @@ import { ReactComponent as BlockIcon } from '@material-symbols/svg-600/outlined/
import { debounce } from 'lodash';
import { fetchDomainBlocks, expandDomainBlocks } from '../../actions/domain_blocks';
import { ColumnBackButtonSlim } from '../../components/column_back_button';
import { LoadingIndicator } from '../../components/loading_indicator';
import ScrollableList from '../../components/scrollable_list';
import DomainContainer from '../../containers/domain_container';
@ -61,9 +60,7 @@ class Blocks extends ImmutablePureComponent {
const emptyMessage = <FormattedMessage id='empty_column.domain_blocks' defaultMessage='There are no blocked domains yet.' />;
return (
<Column bindToDocument={!multiColumn} icon='ban' iconComponent={BlockIcon} heading={intl.formatMessage(messages.heading)}>
<ColumnBackButtonSlim />
<Column bindToDocument={!multiColumn} icon='ban' iconComponent={BlockIcon} heading={intl.formatMessage(messages.heading)} alwaysShowBackButton>
<ScrollableList
scrollKey='domain_blocks'
onLoadMore={this.handleLoadMore}

View file

@ -12,7 +12,6 @@ import { ReactComponent as PersonAddIcon } from '@material-symbols/svg-600/outli
import { debounce } from 'lodash';
import { fetchFollowRequests, expandFollowRequests } from '../../actions/accounts';
import { ColumnBackButtonSlim } from '../../components/column_back_button';
import ScrollableList from '../../components/scrollable_list';
import { me } from '../../initial_state';
import Column from '../ui/components/column';
@ -68,8 +67,7 @@ class FollowRequests extends ImmutablePureComponent {
);
return (
<Column bindToDocument={!multiColumn} icon='user-plus' iconComponent={PersonAddIcon} heading={intl.formatMessage(messages.heading)}>
<ColumnBackButtonSlim />
<Column bindToDocument={!multiColumn} icon='user-plus' iconComponent={PersonAddIcon} heading={intl.formatMessage(messages.heading)} alwaysShowBackButton>
<ScrollableList
scrollKey='follow_requests'
onLoadMore={this.handleLoadMore}

View file

@ -12,7 +12,6 @@ import { ReactComponent as VolumeOffIcon } from '@material-symbols/svg-600/outli
import { debounce } from 'lodash';
import { fetchMutes, expandMutes } from '../../actions/mutes';
import { ColumnBackButtonSlim } from '../../components/column_back_button';
import { LoadingIndicator } from '../../components/loading_indicator';
import ScrollableList from '../../components/scrollable_list';
import AccountContainer from '../../containers/account_container';
@ -62,8 +61,7 @@ class Mutes extends ImmutablePureComponent {
const emptyMessage = <FormattedMessage id='empty_column.mutes' defaultMessage="You haven't muted any users yet." />;
return (
<Column bindToDocument={!multiColumn} icon='volume-off' iconComponent={VolumeOffIcon} heading={intl.formatMessage(messages.heading)}>
<ColumnBackButtonSlim />
<Column bindToDocument={!multiColumn} icon='volume-off' iconComponent={VolumeOffIcon} heading={intl.formatMessage(messages.heading)} alwaysShowBackButton>
<ScrollableList
scrollKey='mutes'
onLoadMore={this.handleLoadMore}

View file

@ -13,7 +13,6 @@ import { ReactComponent as PushPinIcon } from '@material-symbols/svg-600/outline
import { getStatusList } from 'mastodon/selectors';
import { fetchPinnedStatuses } from '../../actions/pin_statuses';
import { ColumnBackButtonSlim } from '../../components/column_back_button';
import StatusList from '../../components/status_list';
import Column from '../ui/components/column';
@ -52,8 +51,7 @@ class PinnedStatuses extends ImmutablePureComponent {
const { intl, statusIds, hasMore, multiColumn } = this.props;
return (
<Column bindToDocument={!multiColumn} icon='thumb-tack' iconComponent={PushPinIcon} heading={intl.formatMessage(messages.heading)} ref={this.setRef}>
<ColumnBackButtonSlim />
<Column bindToDocument={!multiColumn} icon='thumb-tack' iconComponent={PushPinIcon} heading={intl.formatMessage(messages.heading)} ref={this.setRef} alwaysShowBackButton>
<StatusList
statusIds={statusIds}
scrollKey='pinned_statuses'

View file

@ -1,13 +1,15 @@
import { render, fireEvent, screen } from '@testing-library/react';
import { render, fireEvent, screen } from 'mastodon/test_helpers';
import Column from '../column';
const fakeIcon = () => <span />;
describe('<Column />', () => {
describe('<ColumnHeader /> click handler', () => {
it('runs the scroll animation if the column contains scrollable content', () => {
const scrollToMock = jest.fn();
const { container } = render(
<Column heading='notifications'>
<Column heading='notifications' icon='notifications' iconComponent={fakeIcon}>
<div className='scrollable' />
</Column>,
);
@ -17,7 +19,7 @@ describe('<Column />', () => {
});
it('does not try to scroll if there is no scrollable content', () => {
render(<Column heading='notifications' />);
render(<Column heading='notifications' icon='notifications' iconComponent={fakeIcon} />);
fireEvent.click(screen.getByText('notifications'));
});
});

View file

@ -3,15 +3,15 @@ import { PureComponent } from 'react';
import { debounce } from 'lodash';
import ColumnHeader from '../../../components/column_header';
import { isMobile } from '../../../is_mobile';
import { scrollTop } from '../../../scroll';
import ColumnHeader from './column_header';
export default class Column extends PureComponent {
static propTypes = {
heading: PropTypes.string,
alwaysShowBackButton: PropTypes.bool,
icon: PropTypes.string,
iconComponent: PropTypes.func,
children: PropTypes.node,
@ -51,13 +51,14 @@ export default class Column extends PureComponent {
};
render () {
const { heading, icon, iconComponent, children, active, hideHeadingOnMobile } = this.props;
const { heading, icon, iconComponent, children, active, hideHeadingOnMobile, alwaysShowBackButton } = this.props;
const showHeading = heading && (!hideHeadingOnMobile || (hideHeadingOnMobile && !isMobile(window.innerWidth)));
const columnHeaderId = showHeading && heading.replace(/ /g, '-');
const header = showHeading && (
<ColumnHeader icon={icon} iconComponent={iconComponent} active={active} type={heading} onClick={this.handleHeaderClick} columnHeaderId={columnHeaderId} />
<ColumnHeader icon={icon} iconComponent={iconComponent} active={active} title={heading} onClick={this.handleHeaderClick} columnHeaderId={columnHeaderId} showBackButton={alwaysShowBackButton} />
);
return (
<div

View file

@ -1,41 +0,0 @@
import PropTypes from 'prop-types';
import { PureComponent } from 'react';
import classNames from 'classnames';
import { Icon } from 'mastodon/components/icon';
export default class ColumnHeader extends PureComponent {
static propTypes = {
icon: PropTypes.string,
iconComponent: PropTypes.func,
type: PropTypes.string,
active: PropTypes.bool,
onClick: PropTypes.func,
columnHeaderId: PropTypes.string,
};
handleClick = () => {
this.props.onClick();
};
render () {
const { icon, iconComponent, type, active, columnHeaderId } = this.props;
let iconElement = '';
if (icon) {
iconElement = <Icon id={icon} icon={iconComponent} className='column-header__icon' />;
}
return (
<h1 className={classNames('column-header', { active })} id={columnHeaderId || null}>
<button onClick={this.handleClick}>
{iconElement}
{type}
</button>
</h1>
);
}
}