Remove "show more" CW button, display SensitiveContentOverlay instead
This commit is contained in:
parent
a1b063fb55
commit
e3352b89d8
8 changed files with 21 additions and 99 deletions
|
@ -105,10 +105,6 @@ const Status: React.FC<IStatus> = (props) => {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleExpandedToggle = (): void => {
|
|
||||||
dispatch(toggleStatusHidden(actualStatus));
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleHotkeyOpenMedia = (e?: KeyboardEvent): void => {
|
const handleHotkeyOpenMedia = (e?: KeyboardEvent): void => {
|
||||||
const status = actualStatus;
|
const status = actualStatus;
|
||||||
const firstAttachment = status.media_attachments.first();
|
const firstAttachment = status.media_attachments.first();
|
||||||
|
@ -301,7 +297,7 @@ const Status: React.FC<IStatus> = (props) => {
|
||||||
const accountAction = props.accountAction || reblogElement;
|
const accountAction = props.accountAction || reblogElement;
|
||||||
|
|
||||||
const inReview = status.visibility === 'self';
|
const inReview = status.visibility === 'self';
|
||||||
const isSensitive = status.sensitive;
|
const isSensitive = status.hidden;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<HotKeys handlers={handlers} data-testid='status'>
|
<HotKeys handlers={handlers} data-testid='status'>
|
||||||
|
@ -382,8 +378,6 @@ const Status: React.FC<IStatus> = (props) => {
|
||||||
<StatusContent
|
<StatusContent
|
||||||
status={actualStatus}
|
status={actualStatus}
|
||||||
onClick={handleClick}
|
onClick={handleClick}
|
||||||
expanded={!status.hidden}
|
|
||||||
onExpandedToggle={handleExpandedToggle}
|
|
||||||
collapsable
|
collapsable
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -35,49 +35,16 @@ const ReadMoreButton: React.FC<IReadMoreButton> = ({ onClick }) => (
|
||||||
</button>
|
</button>
|
||||||
);
|
);
|
||||||
|
|
||||||
interface ISpoilerButton {
|
|
||||||
onClick: React.MouseEventHandler,
|
|
||||||
hidden: boolean,
|
|
||||||
tabIndex?: number,
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Button to expand status text behind a content warning */
|
|
||||||
const SpoilerButton: React.FC<ISpoilerButton> = ({ onClick, hidden, tabIndex }) => (
|
|
||||||
<button
|
|
||||||
tabIndex={tabIndex}
|
|
||||||
className={classNames(
|
|
||||||
'inline-block rounded-md px-1.5 py-0.5 ml-[0.5em]',
|
|
||||||
'text-gray-900 dark:text-gray-100',
|
|
||||||
'font-bold text-[11px] uppercase',
|
|
||||||
'bg-primary-100 dark:bg-primary-800',
|
|
||||||
'hover:bg-primary-300 dark:hover:bg-primary-600',
|
|
||||||
'focus:bg-primary-200 dark:focus:bg-primary-600',
|
|
||||||
'hover:no-underline',
|
|
||||||
'duration-100',
|
|
||||||
)}
|
|
||||||
onClick={onClick}
|
|
||||||
>
|
|
||||||
{hidden ? (
|
|
||||||
<FormattedMessage id='status.show_more' defaultMessage='Show more' />
|
|
||||||
) : (
|
|
||||||
<FormattedMessage id='status.show_less' defaultMessage='Show less' />
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
);
|
|
||||||
|
|
||||||
interface IStatusContent {
|
interface IStatusContent {
|
||||||
status: Status,
|
status: Status,
|
||||||
expanded?: boolean,
|
|
||||||
onExpandedToggle?: () => void,
|
|
||||||
onClick?: () => void,
|
onClick?: () => void,
|
||||||
collapsable?: boolean,
|
collapsable?: boolean,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Renders the text content of a status */
|
/** Renders the text content of a status */
|
||||||
const StatusContent: React.FC<IStatusContent> = ({ status, expanded = false, onExpandedToggle, onClick, collapsable = false }) => {
|
const StatusContent: React.FC<IStatusContent> = ({ status, onClick, collapsable = false }) => {
|
||||||
const history = useHistory();
|
const history = useHistory();
|
||||||
|
|
||||||
const [hidden, setHidden] = useState(true);
|
|
||||||
const [collapsed, setCollapsed] = useState(false);
|
const [collapsed, setCollapsed] = useState(false);
|
||||||
const [onlyEmoji, setOnlyEmoji] = useState(false);
|
const [onlyEmoji, setOnlyEmoji] = useState(false);
|
||||||
|
|
||||||
|
@ -186,18 +153,6 @@ const StatusContent: React.FC<IStatusContent> = ({ status, expanded = false, onE
|
||||||
startXY.current = undefined;
|
startXY.current = undefined;
|
||||||
};
|
};
|
||||||
|
|
||||||
const handleSpoilerClick: React.EventHandler<React.MouseEvent> = (e) => {
|
|
||||||
e.preventDefault();
|
|
||||||
e.stopPropagation();
|
|
||||||
|
|
||||||
if (onExpandedToggle) {
|
|
||||||
// The parent manages the state
|
|
||||||
onExpandedToggle();
|
|
||||||
} else {
|
|
||||||
setHidden(!hidden);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const parsedHtml = useMemo((): string => {
|
const parsedHtml = useMemo((): string => {
|
||||||
const { contentHtml: html } = status;
|
const { contentHtml: html } = status;
|
||||||
|
|
||||||
|
@ -212,13 +167,11 @@ const StatusContent: React.FC<IStatusContent> = ({ status, expanded = false, onE
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const isHidden = onExpandedToggle ? !expanded : hidden;
|
|
||||||
const withSpoiler = status.spoiler_text.length > 0;
|
const withSpoiler = status.spoiler_text.length > 0;
|
||||||
|
|
||||||
const baseClassName = 'text-gray-900 dark:text-gray-100 break-words text-ellipsis overflow-hidden relative focus:outline-none';
|
const baseClassName = 'text-gray-900 dark:text-gray-100 break-words text-ellipsis overflow-hidden relative focus:outline-none';
|
||||||
|
|
||||||
const content = { __html: parsedHtml };
|
const content = { __html: parsedHtml };
|
||||||
const spoilerContent = { __html: status.spoilerHtml };
|
|
||||||
const directionStyle: React.CSSProperties = { direction: 'ltr' };
|
const directionStyle: React.CSSProperties = { direction: 'ltr' };
|
||||||
const className = classNames(baseClassName, 'status-content', {
|
const className = classNames(baseClassName, 'status-content', {
|
||||||
'cursor-pointer': onClick,
|
'cursor-pointer': onClick,
|
||||||
|
@ -231,37 +184,7 @@ const StatusContent: React.FC<IStatusContent> = ({ status, expanded = false, onE
|
||||||
directionStyle.direction = 'rtl';
|
directionStyle.direction = 'rtl';
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status.spoiler_text.length > 0) {
|
if (onClick) {
|
||||||
return (
|
|
||||||
<div className={className} ref={node} tabIndex={0} style={directionStyle} onMouseDown={handleMouseDown} onMouseUp={handleMouseUp}>
|
|
||||||
<p style={{ marginBottom: isHidden && status.mentions.isEmpty() ? 0 : undefined }}>
|
|
||||||
<span dangerouslySetInnerHTML={spoilerContent} lang={status.language || undefined} />
|
|
||||||
|
|
||||||
<SpoilerButton
|
|
||||||
tabIndex={0}
|
|
||||||
onClick={handleSpoilerClick}
|
|
||||||
hidden={isHidden}
|
|
||||||
/>
|
|
||||||
</p>
|
|
||||||
|
|
||||||
<div
|
|
||||||
tabIndex={!isHidden ? 0 : undefined}
|
|
||||||
className={classNames({
|
|
||||||
'whitespace-pre-wrap': withSpoiler,
|
|
||||||
'hidden': isHidden,
|
|
||||||
'block': !isHidden,
|
|
||||||
})}
|
|
||||||
style={directionStyle}
|
|
||||||
dangerouslySetInnerHTML={content}
|
|
||||||
lang={status.language || undefined}
|
|
||||||
/>
|
|
||||||
|
|
||||||
{!isHidden && status.poll && typeof status.poll === 'string' && (
|
|
||||||
<Poll id={status.poll} status={status.url} />
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
);
|
|
||||||
} else if (onClick) {
|
|
||||||
const output = [
|
const output = [
|
||||||
<div
|
<div
|
||||||
ref={node}
|
ref={node}
|
||||||
|
|
|
@ -81,6 +81,14 @@ const SensitiveContentOverlay = (props: ISensitiveContentOverlay) => {
|
||||||
<Text theme='white' size='sm' weight='medium'>
|
<Text theme='white' size='sm' weight='medium'>
|
||||||
{intl.formatMessage(isUnderReview ? messages.underReviewSubtitle : messages.sensitiveSubtitle)}
|
{intl.formatMessage(isUnderReview ? messages.underReviewSubtitle : messages.sensitiveSubtitle)}
|
||||||
</Text>
|
</Text>
|
||||||
|
|
||||||
|
{status.spoiler_text && (
|
||||||
|
<div className='py-4 italic'>
|
||||||
|
<Text theme='white' size='md' weight='medium'>
|
||||||
|
“<span dangerouslySetInnerHTML={{ __html: status.spoilerHtml }} />”
|
||||||
|
</Text>
|
||||||
|
</div>
|
||||||
|
)}
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<HStack alignItems='center' justifyContent='center' space={2}>
|
<HStack alignItems='center' justifyContent='center' space={2}>
|
||||||
|
|
|
@ -44,7 +44,6 @@ const ScheduledStatus: React.FC<IScheduledStatus> = ({ statusId, ...other }) =>
|
||||||
|
|
||||||
<StatusContent
|
<StatusContent
|
||||||
status={status}
|
status={status}
|
||||||
expanded
|
|
||||||
collapsable
|
collapsable
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -37,10 +37,6 @@ const DetailedStatus: React.FC<IDetailedStatus> = ({
|
||||||
const intl = useIntl();
|
const intl = useIntl();
|
||||||
const node = useRef<HTMLDivElement>(null);
|
const node = useRef<HTMLDivElement>(null);
|
||||||
|
|
||||||
const handleExpandedToggle = () => {
|
|
||||||
onToggleHidden(status);
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleOpenCompareHistoryModal = () => {
|
const handleOpenCompareHistoryModal = () => {
|
||||||
onOpenCompareHistoryModal(status);
|
onOpenCompareHistoryModal(status);
|
||||||
};
|
};
|
||||||
|
@ -51,7 +47,7 @@ const DetailedStatus: React.FC<IDetailedStatus> = ({
|
||||||
if (!account || typeof account !== 'object') return null;
|
if (!account || typeof account !== 'object') return null;
|
||||||
|
|
||||||
const isUnderReview = actualStatus.visibility === 'self';
|
const isUnderReview = actualStatus.visibility === 'self';
|
||||||
const isSensitive = actualStatus.sensitive;
|
const isSensitive = actualStatus.hidden;
|
||||||
|
|
||||||
let statusTypeIcon = null;
|
let statusTypeIcon = null;
|
||||||
|
|
||||||
|
@ -105,11 +101,7 @@ const DetailedStatus: React.FC<IDetailedStatus> = ({
|
||||||
/>
|
/>
|
||||||
) : null}
|
) : null}
|
||||||
|
|
||||||
<StatusContent
|
<StatusContent status={actualStatus} />
|
||||||
status={actualStatus}
|
|
||||||
expanded={!actualStatus.hidden}
|
|
||||||
onExpandedToggle={handleExpandedToggle}
|
|
||||||
/>
|
|
||||||
|
|
||||||
<StatusMedia
|
<StatusMedia
|
||||||
status={actualStatus}
|
status={actualStatus}
|
||||||
|
|
|
@ -56,7 +56,6 @@ const SelectedStatus = ({ statusId }: { statusId: string }) => {
|
||||||
|
|
||||||
<StatusContent
|
<StatusContent
|
||||||
status={status}
|
status={status}
|
||||||
expanded
|
|
||||||
collapsable
|
collapsable
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,6 @@ const PendingStatus: React.FC<IPendingStatus> = ({ idempotencyKey, className, mu
|
||||||
|
|
||||||
<StatusContent
|
<StatusContent
|
||||||
status={status}
|
status={status}
|
||||||
expanded
|
|
||||||
collapsable
|
collapsable
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
|
|
@ -149,6 +149,13 @@ const fixFiltered = (status: ImmutableMap<string, any>) => {
|
||||||
status.delete('filtered');
|
status.delete('filtered');
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/** If the status contains spoiler text, treat it as sensitive. */
|
||||||
|
const fixSensitivity = (status: ImmutableMap<string, any>) => {
|
||||||
|
if (status.get('spoiler_text')) {
|
||||||
|
status.set('sensitive', true);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
export const normalizeStatus = (status: Record<string, any>) => {
|
export const normalizeStatus = (status: Record<string, any>) => {
|
||||||
return StatusRecord(
|
return StatusRecord(
|
||||||
ImmutableMap(fromJS(status)).withMutations(status => {
|
ImmutableMap(fromJS(status)).withMutations(status => {
|
||||||
|
@ -161,6 +168,7 @@ export const normalizeStatus = (status: Record<string, any>) => {
|
||||||
addSelfMention(status);
|
addSelfMention(status);
|
||||||
fixQuote(status);
|
fixQuote(status);
|
||||||
fixFiltered(status);
|
fixFiltered(status);
|
||||||
|
fixSensitivity(status);
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in a new issue