Status interaction action (#39681)
This commit is contained in:
9 files changed
+414
-79
No files matched your search
@@ -16,19 +16,9 @@ import {
|
||||
|
||||
import type { AttachmentArgs } from './testing';
|
||||
import { attachmentArgTypes, attachmentFactory } from './testing';
|
||||
import type { StatusContextType } from './types';
|
||||
import { TypedStatus } from './types';
|
||||
|
||||
type ContextTypes =
|
||||
| 'account'
|
||||
| 'bookmarks'
|
||||
| 'detailed'
|
||||
| 'favourites'
|
||||
| 'home'
|
||||
| 'notifications'
|
||||
| 'public'
|
||||
| 'search'
|
||||
| 'thread';
|
||||
|
||||
interface StatusStoryProps extends AttachmentArgs {
|
||||
// Contents
|
||||
text: string;
|
||||
@@ -51,7 +41,7 @@ interface StatusStoryProps extends AttachmentArgs {
|
||||
|
||||
// Display
|
||||
showThread?: boolean;
|
||||
contextType?: ContextTypes;
|
||||
contextType?: StatusContextType;
|
||||
showCounters?: boolean;
|
||||
favouriteCount?: number;
|
||||
reblogCount?: number;
|
||||
@@ -319,6 +309,7 @@ const meta = {
|
||||
options: [
|
||||
'account',
|
||||
'bookmarks',
|
||||
'composer',
|
||||
'detailed',
|
||||
'favourites',
|
||||
'home',
|
||||
@@ -326,7 +317,7 @@ const meta = {
|
||||
'public',
|
||||
'search',
|
||||
'thread',
|
||||
] satisfies ContextTypes[],
|
||||
] satisfies StatusContextType[],
|
||||
},
|
||||
hidden: categoryDisplay,
|
||||
muted: categoryDisplay,
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
import type { ComponentType, MouseEventHandler, ReactNode } from 'react';
|
||||
|
||||
import StatusContainer from '@/mastodon/containers/status_container';
|
||||
import type { Account as TAccount } from '@/mastodon/models/account';
|
||||
import type { Status as TStatus } from '@/mastodon/models/status';
|
||||
|
||||
@@ -7,15 +8,55 @@ import Status from '../status';
|
||||
|
||||
import type { StatusHeaderRenderFn } from './header';
|
||||
|
||||
// Taken from the Status component.
|
||||
export interface StatusProps {
|
||||
status: TStatus;
|
||||
export type StatusContextType =
|
||||
| 'account'
|
||||
| 'bookmarks'
|
||||
| 'composer'
|
||||
| 'detailed'
|
||||
| 'favourites'
|
||||
| 'home'
|
||||
| `list:${string}`
|
||||
| 'notifications'
|
||||
| 'public'
|
||||
| 'search'
|
||||
| 'thread';
|
||||
|
||||
export interface StatusContainerProps {
|
||||
id?: string | null;
|
||||
account?: TAccount;
|
||||
children?: ReactNode;
|
||||
previousId?: string;
|
||||
nextInReplyToId?: string;
|
||||
rootId?: string;
|
||||
onClick?: MouseEventHandler<HTMLDivElement>;
|
||||
muted?: boolean;
|
||||
hidden?: boolean;
|
||||
unread?: boolean;
|
||||
featured?: boolean;
|
||||
showThread?: boolean;
|
||||
showActions?: boolean;
|
||||
isQuotedPost?: boolean;
|
||||
shouldHighlightOnMount?: boolean;
|
||||
contextType?: StatusContextType;
|
||||
withCounters?: boolean;
|
||||
unfocusable?: boolean;
|
||||
headerRenderFn?: StatusHeaderRenderFn;
|
||||
getScrollPosition?: () => null | { height: number; top: number };
|
||||
updateScrollBottom?: (snapshot: number) => void;
|
||||
cacheMediaWidth?: (width: number) => void;
|
||||
cachedMediaWidth?: number;
|
||||
scrollKey?: string;
|
||||
skipPrepend?: boolean;
|
||||
avatarSize?: number;
|
||||
withDismiss?: boolean;
|
||||
}
|
||||
|
||||
export const TypedStatusContainer =
|
||||
StatusContainer as ComponentType<StatusContainerProps>;
|
||||
|
||||
// Taken from the Status component.
|
||||
export interface StatusProps extends StatusContainerProps {
|
||||
status: TStatus;
|
||||
nextInReplyToId?: string;
|
||||
onReply: (status: TStatus) => void;
|
||||
onFavourite: (status: TStatus) => void;
|
||||
onReblog: (status: TStatus, event?: unknown) => void;
|
||||
@@ -44,31 +85,12 @@ export interface StatusProps {
|
||||
onToggleCollapsed: (status: TStatus, isCollapsed: boolean) => void;
|
||||
onTranslate: (status: TStatus) => void;
|
||||
onInteractionModal?: (type: string, status: TStatus) => void;
|
||||
muted?: boolean;
|
||||
hidden?: boolean;
|
||||
unread?: boolean;
|
||||
featured?: boolean;
|
||||
showThread?: boolean;
|
||||
showActions?: boolean;
|
||||
isQuotedPost?: boolean;
|
||||
shouldHighlightOnMount?: boolean;
|
||||
getScrollPosition?: () => null | { height: number; top: number };
|
||||
updateScrollBottom?: (snapshot: number) => void;
|
||||
cacheMediaWidth?: (width: number) => void;
|
||||
cachedMediaWidth?: number;
|
||||
scrollKey?: string;
|
||||
skipPrepend?: boolean;
|
||||
avatarSize?: number;
|
||||
deployPictureInPicture: (
|
||||
status: TStatus,
|
||||
type: string,
|
||||
mediaProps: unknown,
|
||||
) => void;
|
||||
unfocusable?: boolean;
|
||||
headerRenderFn?: StatusHeaderRenderFn;
|
||||
pictureInPicture: Immutable.Map<'inUse' | 'available', boolean>;
|
||||
contextType?: string;
|
||||
withCounters?: boolean;
|
||||
}
|
||||
|
||||
export const TypedStatus = Status as ComponentType<StatusProps>;
|
||||
@@ -1,16 +1,16 @@
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react';
|
||||
import type { ComponentType, ReactNode } from 'react';
|
||||
|
||||
import { defineMessage, FormattedMessage, useIntl } from 'react-intl';
|
||||
|
||||
import type { Map as ImmutableMap } from 'immutable';
|
||||
|
||||
import type { Merge } from 'type-fest';
|
||||
|
||||
import CancelFillIcon from '@/material-icons/400-24px/cancel-fill.svg?react';
|
||||
import { fetchRelationships } from 'mastodon/actions/accounts';
|
||||
import { revealAccount } from 'mastodon/actions/accounts_typed';
|
||||
import { fetchStatus } from 'mastodon/actions/statuses';
|
||||
import { LearnMoreLink } from 'mastodon/components/learn_more_link';
|
||||
import StatusContainer from 'mastodon/containers/status_container';
|
||||
import { domain } from 'mastodon/initial_state';
|
||||
import type { Account } from 'mastodon/models/account';
|
||||
import type { Status } from 'mastodon/models/status';
|
||||
@@ -23,6 +23,8 @@ import { Button } from './button';
|
||||
import { IconButton } from './icon_button';
|
||||
import type { StatusHeaderRenderFn } from './status/header';
|
||||
import { StatusHeader } from './status/header';
|
||||
import { TypedStatusContainer } from './status/types';
|
||||
import type { StatusContainerProps, StatusContextType } from './status/types';
|
||||
|
||||
const MAX_QUOTE_POSTS_NESTING_LEVEL = 1;
|
||||
|
||||
@@ -143,24 +145,9 @@ const FilteredQuote: React.FC<{
|
||||
);
|
||||
};
|
||||
|
||||
// Adds a wrapper around StatusContainer as the types aren't inheriting correctly with Redux + React 19.
|
||||
// TODO: Remove this after the Status component is in TS.
|
||||
interface StatusContainerForQuotesProps {
|
||||
id?: string | null;
|
||||
contextType?: string;
|
||||
isQuotedPost?: boolean;
|
||||
avatarSize?: number;
|
||||
headerRenderFn?: StatusHeaderRenderFn;
|
||||
children?: ReactNode;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
|
||||
const StatusContainerWithChildren =
|
||||
StatusContainer as unknown as ComponentType<StatusContainerForQuotesProps>;
|
||||
|
||||
interface QuotedStatusProps {
|
||||
quote: QuoteMap;
|
||||
contextType?: string;
|
||||
contextType?: StatusContextType;
|
||||
parentQuotePostId?: string | null;
|
||||
variant?: 'full' | 'link';
|
||||
nestingLevel?: number;
|
||||
@@ -354,7 +341,7 @@ export const QuotedStatus: React.FC<QuotedStatusProps> = ({
|
||||
|
||||
return (
|
||||
<div className='status__quote'>
|
||||
<StatusContainerWithChildren
|
||||
<TypedStatusContainer
|
||||
isQuotedPost
|
||||
id={quotedStatusId}
|
||||
contextType={contextType}
|
||||
@@ -372,16 +359,17 @@ export const QuotedStatus: React.FC<QuotedStatusProps> = ({
|
||||
nestingLevel={nestingLevel + 1}
|
||||
/>
|
||||
)}
|
||||
</StatusContainerWithChildren>
|
||||
</TypedStatusContainer>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export interface StatusQuoteManagerProps {
|
||||
id: string;
|
||||
contextType?: string;
|
||||
[key: string]: unknown;
|
||||
}
|
||||
export type StatusQuoteManagerProps = Merge<
|
||||
StatusContainerProps,
|
||||
{
|
||||
id: string;
|
||||
}
|
||||
>;
|
||||
|
||||
/**
|
||||
* This wrapper component takes a status ID and, if the associated status
|
||||
@@ -399,15 +387,15 @@ export const StatusQuoteManager = (props: StatusQuoteManagerProps) => {
|
||||
|
||||
if (quote) {
|
||||
return (
|
||||
<StatusContainerWithChildren {...props}>
|
||||
<TypedStatusContainer {...props}>
|
||||
<QuotedStatus
|
||||
quote={quote}
|
||||
parentQuotePostId={status?.get('id') as string}
|
||||
contextType={props.contextType}
|
||||
/>
|
||||
</StatusContainerWithChildren>
|
||||
</TypedStatusContainer>
|
||||
);
|
||||
}
|
||||
|
||||
return <StatusContainerWithChildren {...props} />;
|
||||
return <TypedStatusContainer {...props} />;
|
||||
};
|
||||
Reference in new issue
Block a user