Remove this sensitive content overlay fuckery

Signed-off-by: marcin mikołajczak <git@mkljczk.pl>
This commit is contained in:
marcin mikołajczak 2024-08-23 23:50:00 +02:00
parent f648a68edf
commit 5d17752231
12 changed files with 45 additions and 102 deletions

View file

@ -13,7 +13,7 @@ interface IAttachmentThumbs {
}
const AttachmentThumbs = (props: IAttachmentThumbs) => {
const { media, onClick, sensitive } = props;
const { media, onClick } = props;
const dispatch = useAppDispatch();
const fallback = <div className='media-gallery--compact' />;
@ -27,8 +27,6 @@ const AttachmentThumbs = (props: IAttachmentThumbs) => {
onOpenMedia={onOpenMedia}
height={50}
compact
sensitive={sensitive}
visible
/>
</Suspense>

View file

@ -55,7 +55,6 @@ interface IItem {
size: number;
onClick: (index: number) => void;
displayWidth?: number;
visible: boolean;
dimensions: Dimensions;
last?: boolean;
total: number;
@ -66,7 +65,6 @@ const Item: React.FC<IItem> = ({
index,
onClick,
standalone = false,
visible,
dimensions,
last,
total,
@ -266,19 +264,17 @@ const Item: React.FC<IItem> = ({
hash={attachment.blurhash}
className='media-gallery__preview'
/>
{visible && thumbnail}
{thumbnail}
</div>
);
};
interface IMediaGallery {
sensitive?: boolean;
media: Array<MediaAttachment>;
height?: number;
onOpenMedia: (media: Array<MediaAttachment>, index: number) => void;
defaultWidth?: number;
cacheWidth?: (width: number) => void;
visible?: boolean;
displayMedia?: string;
compact?: boolean;
className?: string;
@ -538,7 +534,6 @@ const MediaGallery: React.FC<IMediaGallery> = (props) => {
index={i}
size={sizeData.size}
displayWidth={sizeData.width}
visible={!!props.visible}
dimensions={sizeData.itemsDimensions[i]}
last={i === ATTACHMENT_LIMIT - 1}
total={media.length}

View file

@ -1,5 +1,5 @@
import clsx from 'clsx';
import React, { MouseEventHandler, useEffect, useRef, useState } from 'react';
import React, { MouseEventHandler } from 'react';
import { defineMessages, useIntl } from 'react-intl';
import { useHistory } from 'react-router-dom';
@ -34,16 +34,6 @@ const QuotedStatus: React.FC<IQuotedStatus> = ({ status, onCancel, compose }) =>
const intl = useIntl();
const history = useHistory();
const overlay = useRef<HTMLDivElement>(null);
const [minHeight, setMinHeight] = useState(208);
useEffect(() => {
if (overlay.current) {
setMinHeight(overlay.current.getBoundingClientRect().height);
}
}, [overlay.current]);
const handleExpandClick: MouseEventHandler<HTMLDivElement> = (e) => {
if (!status) return;
const account = status.account;
@ -105,15 +95,7 @@ const QuotedStatus: React.FC<IQuotedStatus> = ({ status, onCancel, compose }) =>
<StatusReplyMentions status={status} hoverable={false} />
{status.event ? <EventPreview status={status} hideAction /> : (
<Stack
className='relative z-0'
style={{ minHeight: status.sensitive ? Math.max(minHeight, 208) + 12 : undefined }}
>
<SensitiveContentOverlay
status={status}
ref={overlay}
/>
<Stack className='relative z-0'>
<Stack space={4}>
<StatusContent
status={status}
@ -122,9 +104,14 @@ const QuotedStatus: React.FC<IQuotedStatus> = ({ status, onCancel, compose }) =>
{status.quote_id && <QuotedStatusIndicator statusId={status.quote_id} />}
{status.media_attachments.length > 0 && (
<StatusMedia status={status} muted={compose} />
)}
<div className='relative'>
<SensitiveContentOverlay
status={status}
/>
{status.media_attachments.length > 0 && (
<StatusMedia status={status} muted={compose} />
)}
</div>
</Stack>
</Stack>
)}

View file

@ -5,6 +5,7 @@ import { FormattedMessage } from 'react-intl';
import { Link } from 'react-router-dom';
import Icon from 'soapbox/components/icon';
import { Text } from 'soapbox/components/ui';
import { onlyEmoji as isOnlyEmoji } from 'soapbox/utils/rich-content';
import { getTextDirection } from '../utils/rtl';
@ -15,7 +16,6 @@ import Markup from './markup';
import Poll from './polls/poll';
import type { Sizes } from 'soapbox/components/ui/text/text';
// import type { Status } from 'soapbox/normalizers';
import type { MinifiedStatus } from 'soapbox/reducers/statuses';
const MAX_HEIGHT = 642; // 20px * 32 (+ 2px padding at the top)
@ -156,8 +156,22 @@ const StatusContent: React.FC<IStatusContent> = React.memo(({
'leading-normal big-emoji': onlyEmoji,
});
const spoilerText = status.spoilerMapHtml && status.currentLanguage
? status.spoilerMapHtml[status.currentLanguage] || status.spoilerHtml
: status.spoilerHtml;
const output = [];
if (spoilerText) {
output.push(
<Text className='mb-2' size='2xl' weight='medium'>
<span dangerouslySetInnerHTML={{ __html: spoilerText }} />
</Text>,
);
}
if (onClick) {
const output = [
output.push(
<Markup
ref={node}
tabIndex={0}
@ -169,7 +183,7 @@ const StatusContent: React.FC<IStatusContent> = React.memo(({
>
{content}
</Markup>,
];
);
if (collapsed) {
output.push(<ReadMoreButton onClick={onClick} key='read-more' />);
@ -184,7 +198,7 @@ const StatusContent: React.FC<IStatusContent> = React.memo(({
return <div className={clsx({ 'bg-gray-100 dark:bg-primary-800 rounded-md p-4': hasPoll })}>{output}</div>;
} else {
const output = [
output.push(
<Markup
ref={node}
tabIndex={0}
@ -198,7 +212,7 @@ const StatusContent: React.FC<IStatusContent> = React.memo(({
>
{content}
</Markup>,
];
);
if (status.poll_id) {
output.push(<Poll id={status.poll_id} key='poll' status={status} />);

View file

@ -59,7 +59,6 @@ const StatusMedia: React.FC<IStatusMedia> = ({
<AttachmentThumbs
media={status.media_attachments}
onClick={onClick}
sensitive={status.sensitive}
/>
);
} else if (size === 1 && firstAttachment.type === 'video') {
@ -101,10 +100,8 @@ const StatusMedia: React.FC<IStatusMedia> = ({
<Suspense fallback={renderLoadingMediaGallery()}>
<MediaGallery
media={status.media_attachments}
sensitive={status.sensitive}
height={285}
onOpenMedia={openMedia}
visible={visible}
/>
</Suspense>
);

View file

@ -1,5 +1,5 @@
import clsx from 'clsx';
import React, { useCallback, useEffect, useRef, useState } from 'react';
import React, { useCallback, useEffect, useRef } from 'react';
import { defineMessages, useIntl, FormattedList, FormattedMessage } from 'react-intl';
import { Link, useHistory } from 'react-router-dom';
@ -79,9 +79,6 @@ const Status: React.FC<IStatus> = (props) => {
const { boostModal } = useSettings();
const didShowCard = useRef(false);
const node = useRef<HTMLDivElement>(null);
const overlay = useRef<HTMLDivElement>(null);
const [minHeight, setMinHeight] = useState(208);
const getStatus = useCallback(makeGetStatus(), []);
const actualStatus = useAppSelector(state => status.reblog_id && getStatus(state, { id: status.reblog_id }) || status)!;
@ -97,12 +94,6 @@ const Status: React.FC<IStatus> = (props) => {
didShowCard.current = Boolean(!muted && !hidden && status?.card);
}, []);
useEffect(() => {
if (overlay.current) {
setMinHeight(overlay.current.getBoundingClientRect().height);
}
}, [overlay.current]);
const handleClick = (e?: React.MouseEvent): void => {
e?.stopPropagation();
@ -426,15 +417,7 @@ const Status: React.FC<IStatus> = (props) => {
<div className='status__content-wrapper'>
<StatusReplyMentions status={actualStatus} hoverable={hoverable} />
<Stack
className='relative z-0'
style={{ minHeight: actualStatus.sensitive ? Math.max(minHeight, 208) + 12 : undefined }}
>
<SensitiveContentOverlay
status={actualStatus}
ref={overlay}
/>
<Stack className='relative z-0'>
{actualStatus.event ? <EventPreview className='shadow-xl' status={actualStatus} /> : (
<Stack space={4}>
<StatusContent
@ -447,7 +430,8 @@ const Status: React.FC<IStatus> = (props) => {
<TranslateButton status={actualStatus} />
{(quote || actualStatus.card || actualStatus.media_attachments.length > 0) && (
<Stack space={4}>
<Stack space={4} className='relative'>
<SensitiveContentOverlay status={actualStatus} />
<StatusMedia
status={actualStatus}
muted={muted}

View file

@ -21,7 +21,7 @@ const messages = defineMessages({
});
interface ISensitiveContentOverlay {
status: Pick<Status, 'id' | 'sensitive' | 'hidden' | 'media_attachments' | 'currentLanguage' | 'spoilerHtml' | 'spoilerMapHtml' | 'spoiler_text'>;
status: Pick<Status, 'id' | 'sensitive' | 'hidden' | 'media_attachments' | 'currentLanguage'>;
}
const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveContentOverlay>((props, ref) => {
@ -47,10 +47,6 @@ const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveConte
if (visible && !showHideButton) return null;
const spoilerText = status.currentLanguage
? status.spoilerMapHtml![status.currentLanguage] || status.spoilerHtml
: status.spoilerHtml;
return (
<div
className={clsx('absolute z-40', {
@ -79,14 +75,6 @@ const SensitiveContentOverlay = React.forwardRef<HTMLDivElement, ISensitiveConte
<Text theme='white' size='sm' weight='medium'>
{intl.formatMessage(messages.sensitiveSubtitle)}
</Text>
{status.spoiler_text && (
<div className='py-4 italic'>
<Text className='line-clamp-6' theme='white' size='md' weight='medium'>
&ldquo;<span dangerouslySetInnerHTML={{ __html: spoilerText }} />&rdquo;
</Text>
</div>
)}
</div>
<HStack alignItems='center' justifyContent='center' space={2}>

View file

@ -40,8 +40,8 @@ const AccountGallery = () => {
} = useAccountLookup(username, { withRelationship: true });
const attachments: ImmutableList<AccountGalleryAttachment> = useAppSelector((state) => account ? getAccountGallery(state, account.id) : ImmutableList());
const isLoading = useAppSelector((state) => state.timelines.get(`account:${account?.id}:media`)?.isLoading);
const hasMore = useAppSelector((state) => state.timelines.get(`account:${account?.id}:media`)?.hasMore);
const isLoading = useAppSelector((state) => state.timelines.get(`account:${account?.id}:with_replies:media`)?.isLoading);
const hasMore = useAppSelector((state) => state.timelines.get(`account:${account?.id}:with_replies:media`)?.hasMore);
const node = useRef<HTMLDivElement>(null);

View file

@ -61,7 +61,6 @@ const StatusCheckBox: React.FC<IStatusCheckBox> = ({ id, disabled }) => {
media = (
<MediaGallery
media={status.media_attachments}
sensitive={status.sensitive}
height={110}
onOpenMedia={noop}
visible

View file

@ -1,4 +1,4 @@
import React, { useEffect, useRef, useState } from 'react';
import React, { useRef } from 'react';
import { FormattedDate, FormattedMessage, useIntl } from 'react-intl';
import { Link } from 'react-router-dom';
@ -31,15 +31,6 @@ const DetailedStatus: React.FC<IDetailedStatus> = ({
const intl = useIntl();
const node = useRef<HTMLDivElement>(null);
const overlay = useRef<HTMLDivElement>(null);
const [minHeight, setMinHeight] = useState(208);
useEffect(() => {
if (overlay.current) {
setMinHeight(overlay.current.getBoundingClientRect().height);
}
}, [overlay.current]);
const handleOpenCompareHistoryModal = () => {
onOpenCompareHistoryModal(status);
@ -124,15 +115,7 @@ const DetailedStatus: React.FC<IDetailedStatus> = ({
<StatusReplyMentions status={actualStatus} />
<Stack
className='relative z-0'
style={{ minHeight: actualStatus.sensitive ? Math.max(minHeight, 208) + 12 : undefined }}
>
<SensitiveContentOverlay
status={status}
ref={overlay}
/>
<Stack className='relative z-0'>
<Stack space={4}>
<StatusContent
status={actualStatus}
@ -143,7 +126,9 @@ const DetailedStatus: React.FC<IDetailedStatus> = ({
<TranslateButton status={actualStatus} />
{(withMedia && (quote || actualStatus.card || actualStatus.media_attachments.length > 0)) && (
<Stack space={4}>
<Stack space={4} className='relative'>
<SensitiveContentOverlay status={status} />
<StatusMedia status={actualStatus} />
{quote}

View file

@ -114,9 +114,6 @@ const normalizeStatus = (status: BaseStatus & {
mentions = [selfMention, ...mentions];
}
// If the status contains spoiler text, treat it as sensitive.
const sensitive = !!status.spoiler_text || status.sensitive;
// Normalize event
let event: BaseStatus['event'] & ({
banner: MediaAttachment | null;
@ -162,8 +159,7 @@ const normalizeStatus = (status: BaseStatus & {
account: normalizeAccount(status.account),
accounts: status.accounts?.map(normalizeAccount),
mentions,
sensitive,
hidden: sensitive,
hidden: status.sensitive,
/** Rewrite `<p></p>` to empty string. */
content: status.content === '<p></p>' ? '' : status.content,
filtered: status.filtered?.map(result => result.filter.title),

View file

@ -206,7 +206,7 @@ type AccountGalleryAttachment = MediaAttachment & {
}
const getAccountGallery = createSelector([
(state: RootState, id: string) => state.timelines.get(`account:${id}:media`)?.items || ImmutableOrderedSet<string>(),
(state: RootState, id: string) => state.timelines.get(`account:${id}:with_replies:media`)?.items || ImmutableOrderedSet<string>(),
(state: RootState) => state.statuses,
], (statusIds, statuses) =>
statusIds.reduce((medias: ImmutableList<AccountGalleryAttachment>, statusId: string) => {