mirror of
https://github.com/mastodon/mastodon.git
synced 2026-09-27 17:07:48 -05:00
Status redesign: Make statuses clickable again (#40648)
This commit is contained in:
@@ -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,
|
||||
|
||||
@@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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({
|
||||
|
||||
Reference in New Issue
Block a user