Status redesign: Make statuses clickable again (#40648)

This commit is contained in:
Echo
2026-09-22 12:09:34 +00:00
committed by GitHub
parent 4d818a63db
commit f20e68ffe3
5 changed files with 50 additions and 29 deletions

View File

@@ -140,6 +140,14 @@ export function useStatusHandlers({
const onOpenClick: React.MouseEventHandler = useCallback(
(event) => {
const target = event.target;
if (
!(target instanceof HTMLElement) ||
target.closest('a, button') ||
contextType === 'detailed'
) {
return;
}
event.preventDefault();
if (event.button === 0 && !(event.ctrlKey || event.metaKey)) {
@@ -151,7 +159,7 @@ export function useStatusHandlers({
onOpenCallback(true);
}
},
[onOpenCallback],
[contextType, onOpenCallback],
);
const acct = status?.account.acct;
@@ -202,7 +210,7 @@ export function useStatusHandlers({
onOpenClick,
onFilterToggle,
onMention,
onOpen: () => {
onOpenCallback: () => {
onOpenCallback();
},
onOpenMedia,

View File

@@ -52,7 +52,7 @@ export const StatusMeta: React.FC<{
return (
<div className={classes.meta}>
<ol>
<ul>
<FormattedMessage
id='status.replies_count'
defaultMessage='{count, plural, one {{counter} reply} other {{counter} replies}}'
@@ -98,9 +98,9 @@ export const StatusMeta: React.FC<{
/>
</Link>
</li>
</ol>
</ul>
<ol>
<ul>
<li>
<FormattedDateWrapper
value={createdAt}
@@ -113,7 +113,7 @@ export const StatusMeta: React.FC<{
</li>
{applicationDisplay && <li>{applicationDisplay}</li>}
<li>{visibility}</li>
</ol>
</ul>
</div>
);
};

View File

@@ -4,6 +4,7 @@ import classNames from 'classnames';
import type { Merge } from 'type-fest';
import type { ExpandedStatusShape } from '@/mastodon/models/status';
import { selectExpandedStatus } from '@/mastodon/selectors/statuses';
import { createAppSelector, useAppSelector } from '@/mastodon/store';
@@ -15,9 +16,9 @@ import { StatusAttachments } from './attachments';
import { StatusContent } from './content';
import { StatusHashtagBar } from './hashtag_bar';
import { StatusRedesignHeader } from './header';
import type { StatusHandlers } from './hooks';
import {
StatusContext,
useStatusContext,
useStatusHandlers,
useTextForScreenReader,
} from './hooks';
@@ -107,7 +108,8 @@ export const StatusRedesign: React.FC<StatusRedesignProps> = ({
showDespiteFilter,
onFilterToggle,
onTranslate,
...handlers
onOpenCallback,
onOpenClick,
} = useStatusHandlers({
status,
contextType,
@@ -119,10 +121,8 @@ export const StatusRedesign: React.FC<StatusRedesignProps> = ({
}
const hotkeysProps = {
handlers: {
...handlers,
onTranslate,
},
status,
onOpen,
muted,
unfocusable,
'data-id': id,
@@ -146,6 +146,7 @@ export const StatusRedesign: React.FC<StatusRedesignProps> = ({
<StatusContext.Provider value={{ id, contextType }}>
<StatusHotkeys
{...hotkeysProps}
onClick={onOpenClick}
className={classNames(
classes.root,
variant === 'thread' && classes.variantThread,
@@ -194,7 +195,7 @@ export const StatusRedesign: React.FC<StatusRedesignProps> = ({
<StatusContent
status={status}
statusContent={statusContent}
onReadMore={handlers.onOpen}
onReadMore={onOpenCallback}
onTranslate={onTranslate}
collapsible
>
@@ -238,27 +239,28 @@ export const StatusRedesign: React.FC<StatusRedesignProps> = ({
};
interface StatusHotkeysProps {
children: React.ReactNode;
status: ExpandedStatusShape;
onOpen?: () => void;
muted?: boolean;
unfocusable?: boolean;
children: React.ReactNode;
handlers: Omit<
StatusHandlers,
| 'isFiltered'
| 'showDespiteFilter'
| 'onOpenClick'
| 'onHeaderClick'
| 'onExpandedToggle'
| 'onFilterToggle'
>;
}
const StatusHotkeys = ({
children,
status,
onOpen,
muted,
unfocusable,
children,
handlers,
...props
}: StatusHotkeysProps & React.ComponentPropsWithoutRef<'article'>) => {
const { contextType } = useStatusContext();
const handlers = useStatusHandlers({
status,
contextType,
onOpen,
});
if (muted) {
return <article {...props}>{children}</article>;
}
@@ -273,7 +275,7 @@ const StatusHotkeys = ({
boost: handlers.onBoost,
quote: handlers.onQuote,
mention: handlers.onMention,
open: handlers.onOpen,
open: handlers.onOpenCallback,
openProfile: handlers.onOpenProfile,
toggleHidden: handlers.onToggleHidden,
// TODO: This is handled in a child component, so needs to be fixed.

View File

@@ -14,10 +14,12 @@
grid-auto-rows: auto;
row-gap: var(--space-2);
padding: var(--space-4);
cursor: pointer;
}
.variantPage {
padding: var(--space-2) var(--space-4);
cursor: auto;
}
.variantThread {
@@ -232,6 +234,8 @@
@include mixins.type-micro;
display: flex;
gap: var(--space-4);
flex-wrap: wrap;
justify-content: space-between;
color: var(--color-text-secondary);
padding-block-start: var(--space-2);
@@ -240,8 +244,9 @@
margin-inline: calc(-1 * var(--space-4));
padding-inline: var(--space-4);
> ol {
> ul {
display: flex;
flex-wrap: wrap;
gap: var(--space-1);
}

View File

@@ -10,6 +10,7 @@ import { BookmarkSimpleIcon } from '@phosphor-icons/react';
import { Helmet } from '@unhead/react/helmet';
import { statusInteraction } from '@/mastodon/actions/interactions_typed';
import { fetchStatus } from '@/mastodon/actions/statuses';
import { ToggleIconButton } from '@/mastodon/components/button/redesign';
import { Column } from '@/mastodon/components/column';
import {
@@ -71,6 +72,7 @@ export const StatusPage: React.FC = () => {
const { statusId } = useParams<{ acct: string; statusId: string }>();
const { multiColumn } = useColumnsContext();
const intl = useIntl();
const dispatch = useAppDispatch();
const [fullscreen, setFullscreen] = useState(isFullscreen);
useEffect(() => {
@@ -84,7 +86,12 @@ export const StatusPage: React.FC = () => {
};
});
const status = useExpandedStatus(statusId, 'force');
const status = useExpandedStatus(statusId);
useEffect(() => {
dispatch(
fetchStatus(statusId, { forceFetch: true, alsoFetchContext: true }),
);
}, [dispatch, statusId]);
const isLoading = useAppSelector(
(state) => !!state.statuses.getIn([statusId, 'isLoading']),
);
@@ -120,7 +127,6 @@ export const StatusPage: React.FC = () => {
[],
);
const dispatch = useAppDispatch();
const handleBookmarkClick = useCallback(() => {
dispatch(
statusInteraction({