diff --git a/src/components/common/helpers/renderMessageText.tsx b/src/components/common/helpers/renderMessageText.tsx
index 01be7df4..8e482e33 100644
--- a/src/components/common/helpers/renderMessageText.tsx
+++ b/src/components/common/helpers/renderMessageText.tsx
@@ -305,7 +305,7 @@ function processEntity(
if (isSimple) {
const text = renderNestedMessagePart();
if (entity.type === ApiMessageEntityTypes.Spoiler) {
- return {text};
+ return {text};
}
return text;
}
diff --git a/src/components/common/spoiler/Spoiler.scss b/src/components/common/spoiler/Spoiler.scss
index a29b316e..5135962c 100644
--- a/src/components/common/spoiler/Spoiler.scss
+++ b/src/components/common/spoiler/Spoiler.scss
@@ -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;
}
}
diff --git a/src/components/common/spoiler/Spoiler.tsx b/src/components/common/spoiler/Spoiler.tsx
index 817beceb..fd3b5a51 100644
--- a/src/components/common/spoiler/Spoiler.tsx
+++ b/src/components/common/spoiler/Spoiler.tsx
@@ -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 = new Map();
@@ -18,22 +18,17 @@ const spoilersByMessageId: Map = new Map();
const Spoiler: FC = ({
children,
messageId,
- isInactive,
}) => {
const [isRevealed, reveal] = useFlag();
- const handleClick = useCallback(() => {
- if (!messageId) return;
+ const handleClick = useCallback((e: ReactMouseEvent) => {
+ 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 = ({
- {children}
+
+ {children}
+
);
};
diff --git a/src/components/mediaViewer/MediaViewer.tsx b/src/components/mediaViewer/MediaViewer.tsx
index 9cdb3ca4..73875c8e 100644
--- a/src/components/mediaViewer/MediaViewer.tsx
+++ b/src/components/mediaViewer/MediaViewer.tsx
@@ -430,7 +430,7 @@ const MediaViewer: FC = ({
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]);
diff --git a/src/components/middle/message/helpers/copyOptions.ts b/src/components/middle/message/helpers/copyOptions.ts
index 69432db7..633bfc3f 100644
--- a/src/components/middle/message/helpers/copyOptions.ts
+++ b/src/components/middle/message/helpers/copyOptions.ts
@@ -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) {
diff --git a/src/modules/helpers/messageSummary.ts b/src/modules/helpers/messageSummary.ts
index 60ddab03..6b2239d3 100644
--- a/src/modules/helpers/messageSummary.ts
+++ b/src/modules/helpers/messageSummary.ts
@@ -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,