From b5fc584bccd583e64b27f495c753283be48e11e5 Mon Sep 17 00:00:00 2001 From: Echo Date: Fri, 2 Oct 2026 12:38:35 +0000 Subject: [PATCH] Composer redesign: Adds pending quote (#40829) --- .../mastodon/components/skeleton.tsx | 12 +++++++-- .../mastodon/components/status/quote.tsx | 25 +++++++++++++++++++ .../features/compose/redesign/attachments.tsx | 9 ++++--- .../features/compose/redesign/selectors.ts | 10 +++++++- 4 files changed, 49 insertions(+), 7 deletions(-) diff --git a/app/javascript/mastodon/components/skeleton.tsx b/app/javascript/mastodon/components/skeleton.tsx index d6f1aed7238..8407ac715bb 100644 --- a/app/javascript/mastodon/components/skeleton.tsx +++ b/app/javascript/mastodon/components/skeleton.tsx @@ -1,10 +1,18 @@ +import classNames from 'classnames'; + interface Props { width?: number | string; height?: number | string; } -export const Skeleton: React.FC = ({ width, height }) => ( - +export const Skeleton: React.FC< + Props & React.ComponentPropsWithRef<'span'> +> = ({ className, width, height, style, ...props }) => ( + ‌ ); diff --git a/app/javascript/mastodon/components/status/quote.tsx b/app/javascript/mastodon/components/status/quote.tsx index 4e35c66d9a7..8562b5a18fb 100644 --- a/app/javascript/mastodon/components/status/quote.tsx +++ b/app/javascript/mastodon/components/status/quote.tsx @@ -9,6 +9,7 @@ import { Link } from 'react-router-dom'; import { PlayIcon } from '@phosphor-icons/react'; import { revealAccount } from '@/mastodon/actions/accounts_typed'; +import { cancelPasteLinkCompose } from '@/mastodon/actions/compose_typed'; import { fetchStatus } from '@/mastodon/actions/statuses'; import type { ApiAudioAttachmentJSON, @@ -42,6 +43,7 @@ import { EmojiHTML } from '../emoji/html'; import { Icon } from '../icon'; import { PopoverMenuCard } from '../menu/card'; import { RelativeTimestamp } from '../relative_timestamp'; +import { Skeleton } from '../skeleton'; import { onStatusLinksDisabled } from './hooks'; import { StatusImage } from './image'; @@ -70,6 +72,29 @@ export const StatusQuote: React.FC = (props) => { return ; }; +export const StatusQuotePending: React.FC = () => { + const dispatch = useAppDispatch(); + const onCancel = useCallback(() => { + dispatch(cancelPasteLinkCompose()); + }, [dispatch]); + + return ( + + } + afterContent={} + > + + + + + + + + ); +}; + export const QuotedStatus: React.FC<{ id: string; clamp?: boolean; diff --git a/app/javascript/mastodon/features/compose/redesign/attachments.tsx b/app/javascript/mastodon/features/compose/redesign/attachments.tsx index 89d1771e933..a77aa18331a 100644 --- a/app/javascript/mastodon/features/compose/redesign/attachments.tsx +++ b/app/javascript/mastodon/features/compose/redesign/attachments.tsx @@ -1,5 +1,6 @@ import type React from 'react'; +import { StatusQuotePending } from '@/mastodon/components/status/quote'; import { useAppSelector } from '@/mastodon/store'; import classes from './attachments.module.scss'; @@ -14,11 +15,10 @@ import { ComposeUpload } from './upload'; export const ComposeAttachments: React.FC<{ className?: string }> = ({ className, }) => { - const { hasPoll, hasAttachments, quotedStatusId } = useAppSelector( - selectComposeHasAttachments, - ); + const { hasPoll, hasAttachments, quotedStatusId, isFetchingLink } = + useAppSelector(selectComposeHasAttachments); - if (!hasPoll && !hasAttachments && !quotedStatusId) { + if (!hasPoll && !hasAttachments && !quotedStatusId && !isFetchingLink) { return null; } @@ -27,6 +27,7 @@ export const ComposeAttachments: React.FC<{ className?: string }> = ({ {hasPoll && } {hasAttachments && } {quotedStatusId && } + {!quotedStatusId && isFetchingLink && } ); }; diff --git a/app/javascript/mastodon/features/compose/redesign/selectors.ts b/app/javascript/mastodon/features/compose/redesign/selectors.ts index 4afa26546f6..2e217550e1b 100644 --- a/app/javascript/mastodon/features/compose/redesign/selectors.ts +++ b/app/javascript/mastodon/features/compose/redesign/selectors.ts @@ -83,13 +83,21 @@ export const selectComposeHasAttachments = createAppSelector( | Immutable.List | undefined, (state) => Number(state.compose.get('pending_media_attachments')), + (state) => state.compose.get('fetching_link') !== null, ], - (hasPoll, quotedStatusId, attachments, pendingAttachments) => { + ( + hasPoll, + quotedStatusId, + attachments, + pendingAttachments, + isFetchingLink, + ) => { return { hasPoll, hasAttachments: (attachments && attachments.size > 0) || pendingAttachments > 0, quotedStatusId, + isFetchingLink, }; }, );