mirror of
https://github.com/danog/telegram-tt.git
synced 2025-01-21 21:01:29 +01:00
Spoilers: Various fixes
This commit is contained in:
parent
bc18224114
commit
a71a13414a
@ -305,7 +305,7 @@ function processEntity(
|
||||
if (isSimple) {
|
||||
const text = renderNestedMessagePart();
|
||||
if (entity.type === ApiMessageEntityTypes.Spoiler) {
|
||||
return <Spoiler isInactive>{text}</Spoiler>;
|
||||
return <Spoiler>{text}</Spoiler>;
|
||||
}
|
||||
return text;
|
||||
}
|
||||
|
@ -1,31 +1,34 @@
|
||||
.Spoiler {
|
||||
transition: color 250ms ease;
|
||||
|
||||
.text-entity-link {
|
||||
transition: color 250ms ease;
|
||||
}
|
||||
|
||||
&:not(.is-revealed) {
|
||||
&.concealed {
|
||||
cursor: pointer;
|
||||
color: transparent;
|
||||
background-image: url('../../../assets/spoiler-dots-black.png');
|
||||
background-size: auto 100%;
|
||||
background-size: auto min(100%, 1.125rem);
|
||||
border-radius: 0.5rem;
|
||||
|
||||
&.animate {
|
||||
animation: pulse-opacity-light 1.75s linear infinite;
|
||||
html.theme-dark &,
|
||||
html.theme-light .ListItem.selected &,
|
||||
.ActionMessage &,
|
||||
.MediaViewerFooter & {
|
||||
background-image: url('../../../assets/spoiler-dots-white.png');
|
||||
}
|
||||
|
||||
.text-entity-link {
|
||||
color: transparent !important;
|
||||
pointer-events: none;
|
||||
.emoji-only & {
|
||||
background-size: auto 1.125rem;
|
||||
}
|
||||
}
|
||||
|
||||
html.theme-dark &:not(.is-revealed),
|
||||
html.theme-light .ListItem.selected &:not(.is-revealed),
|
||||
html.theme-light .ActionMessage &:not(.is-revealed) {
|
||||
background-image: url('../../../assets/spoiler-dots-white.png');
|
||||
&.animated {
|
||||
animation: pulse-opacity-light 1.75s linear infinite;
|
||||
}
|
||||
|
||||
span {
|
||||
opacity: 1;
|
||||
transition: opacity 250ms ease;
|
||||
}
|
||||
|
||||
&.concealed span {
|
||||
visibility: hidden;
|
||||
opacity: 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,3 +1,4 @@
|
||||
import { MouseEvent as ReactMouseEvent } from 'react';
|
||||
import React, {
|
||||
FC, memo, useCallback, useEffect,
|
||||
} from '../../../lib/teact/teact';
|
||||
@ -10,7 +11,6 @@ import './Spoiler.scss';
|
||||
type OwnProps = {
|
||||
children?: React.ReactNode;
|
||||
messageId?: number;
|
||||
isInactive?: boolean;
|
||||
};
|
||||
|
||||
const spoilersByMessageId: Map<number, VoidFunction[]> = new Map();
|
||||
@ -18,22 +18,17 @@ const spoilersByMessageId: Map<number, VoidFunction[]> = new Map();
|
||||
const Spoiler: FC<OwnProps> = ({
|
||||
children,
|
||||
messageId,
|
||||
isInactive,
|
||||
}) => {
|
||||
const [isRevealed, reveal] = useFlag();
|
||||
|
||||
const handleClick = useCallback(() => {
|
||||
if (!messageId) return;
|
||||
const handleClick = useCallback((e: ReactMouseEvent<HTMLDivElement, MouseEvent>) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
|
||||
spoilersByMessageId.get(messageId)?.forEach((_reveal) => _reveal());
|
||||
spoilersByMessageId.get(messageId!)?.forEach((_reveal) => _reveal());
|
||||
}, [messageId]);
|
||||
|
||||
useEffect(() => {
|
||||
if (isRevealed && messageId) {
|
||||
spoilersByMessageId.delete(messageId);
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (!messageId) {
|
||||
return undefined;
|
||||
}
|
||||
@ -53,12 +48,14 @@ const Spoiler: FC<OwnProps> = ({
|
||||
<span
|
||||
className={buildClassName(
|
||||
'Spoiler',
|
||||
isRevealed && 'is-revealed',
|
||||
!isInactive && 'animate',
|
||||
!isRevealed && 'concealed',
|
||||
!isRevealed && Boolean(messageId) && 'animated',
|
||||
)}
|
||||
onClick={!isInactive && !isRevealed ? handleClick : undefined}
|
||||
onClick={messageId && !isRevealed ? handleClick : undefined}
|
||||
>
|
||||
{children}
|
||||
<span>
|
||||
{children}
|
||||
</span>
|
||||
</span>
|
||||
);
|
||||
};
|
||||
|
@ -430,7 +430,7 @@ const MediaViewer: FC<StateProps> = ({
|
||||
|
||||
return captureEvents(element, {
|
||||
// eslint-disable-next-line max-len
|
||||
excludedClosestSelector: `.backdrop, .navigation, .media-viewer-head, .media-viewer-footer${!shouldCloseOnVideo ? ', .VideoPlayer' : ''}`,
|
||||
excludedClosestSelector: `.backdrop, .navigation, .media-viewer-head, .Spoiler, .media-viewer-footer${!shouldCloseOnVideo ? ', .VideoPlayer' : ''}`,
|
||||
onClick: close,
|
||||
});
|
||||
}, [close, isGif, isZoomed, messageId]);
|
||||
|
@ -5,6 +5,7 @@ import {
|
||||
getMessageMediaHash,
|
||||
getMessagePhoto,
|
||||
getMessageText,
|
||||
getMessageTextWithSpoilers,
|
||||
getMessageWebPagePhoto,
|
||||
getMessageWebPageVideo,
|
||||
hasMessageLocalBlobUrl,
|
||||
@ -52,7 +53,7 @@ export function getMessageCopyOptions(
|
||||
options.push({
|
||||
label: getCopyLabel(hasSelection),
|
||||
handler: () => {
|
||||
const clipboardText = hasSelection && selection ? selection.toString() : text;
|
||||
const clipboardText = hasSelection && selection ? selection.toString() : getMessageTextWithSpoilers(message)!;
|
||||
copyTextToClipboard(clipboardText);
|
||||
|
||||
if (afterEffect) {
|
||||
|
@ -15,30 +15,34 @@ export function getMessageSummaryText(
|
||||
) {
|
||||
const emoji = !noEmoji && getMessageSummaryEmoji(message);
|
||||
const emojiWithSpace = emoji ? `${emoji} ` : '';
|
||||
|
||||
let text = getMessageText(message);
|
||||
if (text) {
|
||||
const { entities } = message.content.text || {};
|
||||
if (entities?.length) {
|
||||
text = entities.reduce((accText, { type, offset, length }) => {
|
||||
if (type !== ApiMessageEntityTypes.Spoiler) {
|
||||
return accText;
|
||||
}
|
||||
|
||||
const spoiler = generateBrailleSpoiler(length);
|
||||
|
||||
return `${accText.substr(0, offset)}${spoiler}${accText.substr(offset + length, accText.length)}`;
|
||||
}, text);
|
||||
}
|
||||
|
||||
text = text.substr(0, truncateLength);
|
||||
}
|
||||
|
||||
const text = getMessageTextWithSpoilers(message)?.substr(0, truncateLength);
|
||||
const description = getMessageSummaryDescription(lang, message, text);
|
||||
|
||||
return `${emojiWithSpace}${description}`;
|
||||
}
|
||||
|
||||
export function getMessageTextWithSpoilers(message: ApiMessage) {
|
||||
const text = getMessageText(message);
|
||||
if (!text) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
const { entities } = message.content.text || {};
|
||||
if (!entities?.length) {
|
||||
return text;
|
||||
}
|
||||
|
||||
return entities.reduce((accText, { type, offset, length }) => {
|
||||
if (type !== ApiMessageEntityTypes.Spoiler) {
|
||||
return accText;
|
||||
}
|
||||
|
||||
const spoiler = generateBrailleSpoiler(length);
|
||||
|
||||
return `${accText.substr(0, offset)}${spoiler}${accText.substr(offset + length, accText.length)}`;
|
||||
}, text);
|
||||
}
|
||||
|
||||
export function getMessageSummaryEmoji(message: ApiMessage) {
|
||||
const {
|
||||
photo, video, audio, voice, document, sticker, poll,
|
||||
|
Loading…
x
Reference in New Issue
Block a user