diff --git a/app/javascript/mastodon/components/status_quoted.tsx b/app/javascript/mastodon/components/status_quoted.tsx
index 5b840b441c..c99f63704e 100644
--- a/app/javascript/mastodon/components/status_quoted.tsx
+++ b/app/javascript/mastodon/components/status_quoted.tsx
@@ -1,3 +1,5 @@
+import { useMemo } from 'react';
+
import { FormattedMessage } from 'react-intl';
import classNames from 'classnames';
@@ -10,9 +12,11 @@ import ChevronRightIcon from '@/material-icons/400-24px/chevron_right.svg?react'
import { Icon } from 'mastodon/components/icon';
import StatusContainer from 'mastodon/containers/status_container';
import type { Status } from 'mastodon/models/status';
+import type { RootState } from 'mastodon/store';
import { useAppSelector } from 'mastodon/store';
import QuoteIcon from '../../images/quote.svg?react';
+import { makeGetStatus } from '../selectors';
const MAX_QUOTE_POSTS_NESTING_LEVEL = 1;
@@ -65,6 +69,10 @@ const QuoteLink: React.FC<{
};
type QuoteMap = ImmutableMap<'state' | 'quoted_status', string | null>;
+type GetStatusSelector = (
+ state: RootState,
+ props: { id?: string | null; contextType?: string },
+) => Status | null;
export const QuotedStatus: React.FC<{
quote: QuoteMap;
@@ -73,34 +81,50 @@ export const QuotedStatus: React.FC<{
nestingLevel?: number;
}> = ({ quote, contextType, nestingLevel = 1, variant = 'full' }) => {
const quotedStatusId = quote.get('quoted_status');
- const state = quote.get('state');
+ const quoteState = quote.get('state');
const status = useAppSelector((state) =>
quotedStatusId ? state.statuses.get(quotedStatusId) : undefined,
);
let quoteError: React.ReactNode = null;
- if (state === 'deleted') {
+ // In order to find out whether the quoted post should be completely hidden
+ // due to a matching filter, we run it through the selector used by `status_container`.
+ // If this returns null even though `status` exists, it's because it's filtered.
+ const getStatus = useMemo(() => makeGetStatus(), []) as GetStatusSelector;
+ const statusWithExtraData = useAppSelector((state) =>
+ getStatus(state, { id: quotedStatusId, contextType }),
+ );
+ const isFilteredAndHidden = status && statusWithExtraData === null;
+
+ if (isFilteredAndHidden) {
+ quoteError = (
+
+ );
+ } else if (quoteState === 'deleted') {
quoteError = (
);
- } else if (state === 'unauthorized') {
+ } else if (quoteState === 'unauthorized') {
quoteError = (
);
- } else if (state === 'pending') {
+ } else if (quoteState === 'pending') {
quoteError = (
);
- } else if (state === 'rejected' || state === 'revoked') {
+ } else if (quoteState === 'rejected' || quoteState === 'revoked') {
quoteError = (