Redesign: Update column headers on pinned Fediverse Feed pages (#40383)

This commit is contained in:
diondiondion
2026-09-04 14:28:15 +00:00
committed by GitHub
parent e3be977a74
commit ee3cb553cd
4 changed files with 176 additions and 31 deletions

View File

@@ -9,7 +9,7 @@ import { connect } from 'react-redux';
import PeopleIcon from '@/material-icons/400-24px/group.svg?react';
import { Column } from '@/mastodon/components/column';
import { ColumnHeader } from '@/mastodon/components/column/header';
import { ColumnHeader as LegacyColumnHeader } from '@/mastodon/components/column/header';
import { injectIntl } from '@/mastodon/components/intl';
import { DismissableBanner } from 'mastodon/components/dismissable_banner';
import { identityContextPropShape, withIdentity } from 'mastodon/identity_context';
@@ -22,9 +22,14 @@ import { expandCommunityTimeline } from '../../actions/timelines';
import StatusListContainer from '../ui/containers/status_list_container';
import ColumnSettingsContainer from './containers/column_settings_container';
import { ColumnHeader, ColumnSettingsMenu } from '@/mastodon/components/column_header';
import { FeedColumnSettings } from '../public_timeline/components/feed_column_settings';
import { MultiColumnMenuItems } from '@/mastodon/components/column_header/multicolumn_settings';
import { isRedesignEnabled } from '@/mastodon/utils/environment';
const messages = defineMessages({
title: { id: 'column.community', defaultMessage: 'Local timeline' },
title_redesign: { id: 'column.this_server', defaultMessage: 'This Server' },
});
const mapStateToProps = (state, { columnId }) => {
@@ -129,21 +134,45 @@ class CommunityTimeline extends PureComponent {
/>
);
const title = intl.formatMessage(isRedesignEnabled() ? messages.title_redesign : messages.title)
return (
<Column bindToDocument={!multiColumn} label={intl.formatMessage(messages.title)}>
<ColumnHeader
icon='users'
iconComponent={PeopleIcon}
active={hasUnread}
title={intl.formatMessage(messages.title)}
onPin={this.handlePin}
onMove={this.handleMove}
pinned={pinned}
multiColumn={multiColumn}
scrollTopOnClick
>
<ColumnSettingsContainer columnId={columnId} />
</ColumnHeader>
<Column bindToDocument={!multiColumn} label={title}>
{isRedesignEnabled() ? (
<ColumnHeader
title={title}
withUnreadMarker={hasUnread}
extraButtons={
<ColumnSettingsMenu
labelPrefix={title}
>
<FeedColumnSettings localOnly columnId={columnId} />
{multiColumn && (
<MultiColumnMenuItems
withDivider
pinned={pinned}
onPin={this.handlePin}
onMove={this.handleMove}
/>
)}
</ColumnSettingsMenu>
}
/>
) : (
<LegacyColumnHeader
icon='users'
iconComponent={PeopleIcon}
active={hasUnread}
title={title}
onPin={this.handlePin}
onMove={this.handleMove}
pinned={pinned}
multiColumn={multiColumn}
scrollTopOnClick
>
<ColumnSettingsContainer columnId={columnId} />
</LegacyColumnHeader>
)}
<StatusListContainer
prepend={<DismissableBanner id='community_timeline'><FormattedMessage id='dismissable_banner.community_timeline' defaultMessage='These are the most recent public posts from people whose accounts are hosted by {domain}.' values={{ domain }} /></DismissableBanner>}

View File

@@ -0,0 +1,85 @@
import { useCallback } from 'react';
import { FormattedMessage } from 'react-intl';
import type {
List as ImmutableList,
Record as ImmutableRecord,
} from 'immutable';
import { changeColumnParams } from '@/mastodon/actions/columns';
import { MenuItemCheckbox } from '@/mastodon/components/menu';
import type { MenuItemCheckboxChangeHandler } from '@/mastodon/components/menu/items';
import { useAppSelector, useAppDispatch } from 'mastodon/store';
import { changeSetting } from '../../../actions/settings';
type Columns = ImmutableList<
ImmutableRecord<{
uuid: string;
params?: string;
}>
>;
export const FeedColumnSettings: React.FC<{
columnId: string | undefined;
localOnly?: boolean;
}> = ({ columnId, localOnly }) => {
const dispatch = useAppDispatch();
const settings = useAppSelector((state) => {
const columns = state.settings.get('columns') as Columns;
const index = columns.findIndex((c) => c.get('uuid') === columnId);
return columnId && index >= 0
? columns.get(index)?.get('params')
: state.settings.get('public');
});
const onChange = useCallback<MenuItemCheckboxChangeHandler>(
({ value, checked }) => {
if (columnId) {
dispatch(changeColumnParams(columnId, ['other', value], checked));
} else {
dispatch(changeSetting(['public', 'other', value], checked));
}
},
[columnId, dispatch],
);
/* eslint-disable @typescript-eslint/no-unsafe-call */
// @ts-expect-error settings isn't typed yet
const onlyMedia = settings.getIn(['other', 'onlyMedia']) as boolean;
// @ts-expect-error settings isn't typed yet
const onlyRemote = settings.getIn(['other', 'onlyRemote']) as boolean;
/* eslint-enable @typescript-eslint/no-unsafe-call */
return (
<>
<MenuItemCheckbox
value='onlyMedia'
checked={onlyMedia}
onChange={onChange}
keepMenuOpenOnClick
>
<FormattedMessage
id='community.column_settings.media_only'
defaultMessage='Media only'
/>
</MenuItemCheckbox>
{!localOnly && (
<MenuItemCheckbox
value='onlyRemote'
checked={onlyRemote}
onChange={onChange}
keepMenuOpenOnClick
>
<FormattedMessage
id='community.column_settings.remote_only'
defaultMessage='Remote only'
/>
</MenuItemCheckbox>
)}
</>
);
};

View File

@@ -9,7 +9,7 @@ import { connect } from 'react-redux';
import PublicIcon from '@/material-icons/400-24px/public.svg?react';
import { Column } from '@/mastodon/components/column';
import { ColumnHeader } from '@/mastodon/components/column/header';
import { ColumnHeader as LegacyColumnHeader } from '@/mastodon/components/column/header';
import { DismissableBanner } from 'mastodon/components/dismissable_banner';
import { injectIntl } from '@/mastodon/components/intl';
import { identityContextPropShape, withIdentity } from 'mastodon/identity_context';
@@ -22,9 +22,14 @@ import { expandPublicTimeline } from '../../actions/timelines';
import StatusListContainer from '../ui/containers/status_list_container';
import ColumnSettingsContainer from './containers/column_settings_container';
import { isRedesignEnabled } from '@/mastodon/utils/environment';
import { ColumnHeader, ColumnSettingsMenu } from '@/mastodon/components/column_header';
import { FeedColumnSettings } from './components/feed_column_settings';
import { MultiColumnMenuItems } from '@/mastodon/components/column_header/multicolumn_settings';
const messages = defineMessages({
title: { id: 'column.public', defaultMessage: 'Federated timeline' },
title_redesign: { id: 'column.other_servers', defaultMessage: 'Other Servers' },
});
const mapStateToProps = (state, { columnId }) => {
@@ -132,21 +137,45 @@ class PublicTimeline extends PureComponent {
/>
);
const title = intl.formatMessage(isRedesignEnabled() ? messages.title_redesign : messages.title)
return (
<Column bindToDocument={!multiColumn} label={intl.formatMessage(messages.title)}>
<ColumnHeader
icon='globe'
iconComponent={PublicIcon}
active={hasUnread}
title={intl.formatMessage(messages.title)}
onPin={this.handlePin}
onMove={this.handleMove}
pinned={pinned}
multiColumn={multiColumn}
scrollTopOnClick
>
<ColumnSettingsContainer columnId={columnId} />
</ColumnHeader>
<Column bindToDocument={!multiColumn} label={title}>
{isRedesignEnabled() ? (
<ColumnHeader
title={title}
withUnreadMarker={hasUnread}
extraButtons={
<ColumnSettingsMenu
labelPrefix={title}
>
<FeedColumnSettings columnId={columnId} />
{multiColumn && (
<MultiColumnMenuItems
withDivider
pinned={pinned}
onPin={this.handlePin}
onMove={this.handleMove}
/>
)}
</ColumnSettingsMenu>
}
/>
) : (
<LegacyColumnHeader
icon='globe'
iconComponent={PublicIcon}
active={hasUnread}
title={title}
onPin={this.handlePin}
onMove={this.handleMove}
pinned={pinned}
multiColumn={multiColumn}
scrollTopOnClick
>
<ColumnSettingsContainer columnId={columnId} />
</LegacyColumnHeader>
)}
<StatusListContainer
prepend={<DismissableBanner id='public_timeline'><FormattedMessage id='dismissable_banner.public_timeline' defaultMessage='These are the most recent public posts from people on the fediverse that people on {domain} follow.' values={{ domain }} /></DismissableBanner>}
@@ -159,7 +188,7 @@ class PublicTimeline extends PureComponent {
/>
<Helmet>
<title>{intl.formatMessage(messages.title)}</title>
<title>{title}</title>
<meta name='robots' content='noindex' />
</Helmet>
</Column>

View File

@@ -475,10 +475,12 @@
"column.mutes": "Muted users",
"column.notifications": "Notifications",
"column.other_collections": "Collections by {name}",
"column.other_servers": "Other Servers",
"column.pins": "Pinned posts",
"column.public": "Federated timeline",
"column.saved_posts": "Saved Posts",
"column.settings": "Column Settings",
"column.this_server": "This Server",
"column.your_collections": "Your Collections",
"column_back_button.label": "Back",
"column_header.hide_settings": "Hide settings",