Message: Allow downloading animated emojis (#6340)
This commit is contained in:
parent
a1d0d55c51
commit
091ea45a1a
@ -1 +1 @@
|
||||
10.9.75
|
||||
12.0.0
|
||||
|
||||
@ -226,6 +226,8 @@ export function buildApiMessageWithChatId(
|
||||
const isProtected = mtpMessage.noforwards || isInvoiceMedia;
|
||||
const isForwardingAllowed = !mtpMessage.noforwards;
|
||||
const emojiOnlyCount = getEmojiOnlyCountForMessage(content, groupedId);
|
||||
if (content.text && emojiOnlyCount) content.text.emojiOnlyCount = emojiOnlyCount;
|
||||
|
||||
const hasComments = mtpMessage.replies?.comments;
|
||||
const senderBoosts = mtpMessage.fromBoostsApplied;
|
||||
const factCheck = mtpMessage.factcheck && buildApiFactCheck(mtpMessage.factcheck);
|
||||
@ -252,7 +254,6 @@ export function buildApiMessageWithChatId(
|
||||
isSilent: mtpMessage.silent,
|
||||
isPinned: mtpMessage.pinned,
|
||||
reactions: mtpMessage.reactions && buildMessageReactions(mtpMessage.reactions),
|
||||
emojiOnlyCount,
|
||||
...(mtpMessage.replyTo && { replyInfo: buildApiReplyInfo(mtpMessage.replyTo, mtpMessage) }),
|
||||
...(mtpMessage.suggestedPost && { suggestedPostInfo: buildApiSuggestedPost(mtpMessage.suggestedPost) }),
|
||||
forwardInfo,
|
||||
@ -453,7 +454,9 @@ export function buildLocalMessage(
|
||||
const localPoll = poll && buildNewPoll(poll, localId);
|
||||
const localTodo = todo && buildNewTodo(todo);
|
||||
|
||||
const formattedText = text ? addTimestampEntities({ text, entities }) : undefined;
|
||||
const formattedText = text ? addTimestampEntities(
|
||||
{ text, entities, emojiOnlyCount: undefined },
|
||||
) : undefined;
|
||||
|
||||
const message = {
|
||||
id: localId,
|
||||
@ -486,14 +489,10 @@ export function buildLocalMessage(
|
||||
} satisfies ApiMessage;
|
||||
|
||||
const emojiOnlyCount = getEmojiOnlyCountForMessage(message.content, message.groupedId);
|
||||
|
||||
const finalMessage: ApiMessage = {
|
||||
...message,
|
||||
...(emojiOnlyCount && { emojiOnlyCount }),
|
||||
};
|
||||
if (emojiOnlyCount && message.content.text) message.content.text.emojiOnlyCount = emojiOnlyCount;
|
||||
|
||||
return {
|
||||
message: finalMessage,
|
||||
message,
|
||||
poll: localPoll,
|
||||
};
|
||||
}
|
||||
@ -542,6 +541,7 @@ export function buildLocalForwardedMessage({
|
||||
} : content.text;
|
||||
const textWithTimestamps = strippedText && addTimestampEntities(strippedText);
|
||||
const emojiOnlyCount = getEmojiOnlyCountForMessage(content, groupedId);
|
||||
if (emojiOnlyCount && textWithTimestamps) textWithTimestamps.emojiOnlyCount = emojiOnlyCount;
|
||||
|
||||
const updatedContent = {
|
||||
...content,
|
||||
@ -572,7 +572,6 @@ export function buildLocalForwardedMessage({
|
||||
isInvertedMedia,
|
||||
...(toThreadId && toChat?.isForum && { isTopicReply: true }),
|
||||
|
||||
...(emojiOnlyCount && { emojiOnlyCount }),
|
||||
// Forward info doesn't get added when user forwards own messages and when forwarding audio
|
||||
...(message.chatId !== currentUserId && !isAudio && !noAuthors && {
|
||||
forwardInfo: {
|
||||
|
||||
@ -577,8 +577,12 @@ export interface ApiFormattedText {
|
||||
entities?: ApiMessageEntity[];
|
||||
}
|
||||
|
||||
export interface ApiFormattedTextWithEmojiOnlyCount extends ApiFormattedText {
|
||||
emojiOnlyCount?: number;
|
||||
}
|
||||
|
||||
export type MediaContent = {
|
||||
text?: ApiFormattedText;
|
||||
text?: ApiFormattedTextWithEmojiOnlyCount;
|
||||
photo?: ApiPhoto;
|
||||
video?: ApiVideo;
|
||||
altVideos?: ApiVideo[];
|
||||
@ -661,7 +665,6 @@ export interface ApiMessage {
|
||||
isForwardingAllowed?: boolean;
|
||||
transcriptionId?: string;
|
||||
isTranscriptionError?: boolean;
|
||||
emojiOnlyCount?: number;
|
||||
reactors?: {
|
||||
nextOffset?: string;
|
||||
count: number;
|
||||
|
||||
@ -826,7 +826,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
||||
});
|
||||
|
||||
const withAppendix = contentClassName.includes('has-appendix');
|
||||
const emojiSize = getCustomEmojiSize(message.emojiOnlyCount);
|
||||
const emojiSize = getCustomEmojiSize(text?.emojiOnlyCount);
|
||||
|
||||
const paidMessageStarsInMeta = !isChatWithUser
|
||||
? (isAlbum && paidMessageStars ? album.messages.length * paidMessageStars : paidMessageStars)
|
||||
|
||||
@ -81,10 +81,10 @@ export function buildContentClassName(
|
||||
classNames.push(peerColorClass);
|
||||
}
|
||||
|
||||
if (!isMedia && message.emojiOnlyCount) {
|
||||
if (!isMedia && text?.emojiOnlyCount) {
|
||||
classNames.push('emoji-only');
|
||||
if (message.emojiOnlyCount <= EMOJI_SIZES) {
|
||||
classNames.push(`emoji-only-${message.emojiOnlyCount}`);
|
||||
if (text.emojiOnlyCount <= EMOJI_SIZES) {
|
||||
classNames.push(`emoji-only-${text.emojiOnlyCount}`);
|
||||
}
|
||||
} else if (hasText) {
|
||||
classNames.push('text');
|
||||
|
||||
@ -119,29 +119,31 @@ export function getMessageCustomShape(message: ApiMessage): boolean {
|
||||
|
||||
const hasOtherFormatting = text?.entities?.some((entity) => entity.type !== ApiMessageEntityTypes.CustomEmoji);
|
||||
|
||||
return Boolean(message.emojiOnlyCount && !hasOtherFormatting);
|
||||
return Boolean(text.emojiOnlyCount && !hasOtherFormatting);
|
||||
}
|
||||
|
||||
export function getMessageSingleRegularEmoji(message: ApiMessage) {
|
||||
export function getMessageSingleRegularEmoji(message: MediaContainer) {
|
||||
const { text } = message.content;
|
||||
|
||||
if (text?.entities?.length || message.emojiOnlyCount !== 1) {
|
||||
if (!text || text.entities?.length || text.emojiOnlyCount !== 1) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return text!.text;
|
||||
return text.text;
|
||||
}
|
||||
|
||||
export function getMessageSingleCustomEmoji(message: ApiMessage): string | undefined {
|
||||
export function getMessageSingleCustomEmoji(message: MediaContainer): string | undefined {
|
||||
const { text } = message.content;
|
||||
|
||||
const firstEntity = text?.entities?.[0];
|
||||
if (text?.entities?.length !== 1
|
||||
|| text.entities[0].type !== ApiMessageEntityTypes.CustomEmoji
|
||||
|| message.emojiOnlyCount !== 1) {
|
||||
|| firstEntity?.type !== ApiMessageEntityTypes.CustomEmoji
|
||||
|| firstEntity.offset !== 0
|
||||
|| firstEntity.length !== text.text.length) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
return text.entities[0].documentId;
|
||||
return firstEntity.documentId;
|
||||
}
|
||||
|
||||
export function getFirstLinkInMessage(message: ApiMessage) {
|
||||
@ -250,7 +252,7 @@ export function isMessageTranslatable(message: ApiMessage, allowOutgoing?: boole
|
||||
const isServiceNotification = isServiceNotificationMessage(message);
|
||||
const isAction = isActionMessage(message);
|
||||
|
||||
return Boolean(text?.text.length && !message.emojiOnlyCount && !game && (allowOutgoing || !message.isOutgoing)
|
||||
return Boolean(text?.text.length && !text.emojiOnlyCount && !game && (allowOutgoing || !message.isOutgoing)
|
||||
&& !isLocal && !isServiceNotification && !isAction && !message.isScheduled);
|
||||
}
|
||||
|
||||
|
||||
@ -274,19 +274,18 @@ export function updateChatMessage<T extends GlobalState>(
|
||||
}
|
||||
}
|
||||
|
||||
let emojiOnlyCount = message?.emojiOnlyCount;
|
||||
let text = message?.content?.text;
|
||||
if (messageUpdate.content) {
|
||||
emojiOnlyCount = getEmojiOnlyCountForMessage(
|
||||
const emojiOnlyCount = getEmojiOnlyCountForMessage(
|
||||
messageUpdate.content, message?.groupedId || messageUpdate.groupedId,
|
||||
);
|
||||
text = messageUpdate.content.text ? addTimestampEntities(messageUpdate.content.text) : text;
|
||||
if (text) text.emojiOnlyCount = emojiOnlyCount;
|
||||
}
|
||||
|
||||
const updatedMessage = omitUndefined({
|
||||
...message,
|
||||
...messageUpdate,
|
||||
emojiOnlyCount,
|
||||
text,
|
||||
});
|
||||
|
||||
@ -305,19 +304,18 @@ export function updateScheduledMessage<T extends GlobalState>(
|
||||
): T {
|
||||
const message = selectScheduledMessage(global, chatId, messageId)!;
|
||||
|
||||
let emojiOnlyCount = message?.emojiOnlyCount;
|
||||
let text = message?.content?.text;
|
||||
if (messageUpdate.content) {
|
||||
emojiOnlyCount = getEmojiOnlyCountForMessage(
|
||||
const emojiOnlyCount = getEmojiOnlyCountForMessage(
|
||||
messageUpdate.content, message?.groupedId || messageUpdate.groupedId,
|
||||
);
|
||||
text = messageUpdate.content.text ? addTimestampEntities(messageUpdate.content.text) : text;
|
||||
if (text) text.emojiOnlyCount = emojiOnlyCount;
|
||||
}
|
||||
|
||||
const updatedMessage = {
|
||||
...message,
|
||||
...messageUpdate,
|
||||
emojiOnlyCount,
|
||||
text,
|
||||
};
|
||||
|
||||
|
||||
@ -3,7 +3,6 @@ import type {
|
||||
} from '../types';
|
||||
import {
|
||||
type ApiMessage,
|
||||
ApiMessageEntityTypes,
|
||||
type MediaContainer,
|
||||
type SizeTarget,
|
||||
} from '../../api/types';
|
||||
@ -16,8 +15,9 @@ import {
|
||||
getMessageInvoice,
|
||||
getMessageMediaHash,
|
||||
getMessagePhoto,
|
||||
getMessageSingleCustomEmoji,
|
||||
getMessageSingleRegularEmoji,
|
||||
getMessageSticker,
|
||||
getMessageText,
|
||||
getMessageVideo,
|
||||
getMessageVoice,
|
||||
getWebPageAudio,
|
||||
@ -31,7 +31,7 @@ import {
|
||||
selectWebPageFromMessage,
|
||||
} from './messages';
|
||||
import { selectSettingsKeys } from './settings';
|
||||
import { selectCustomEmoji } from './symbols';
|
||||
import { selectAnimatedEmoji, selectCustomEmoji } from './symbols';
|
||||
|
||||
export function selectIsMediaNsfw<T extends GlobalState>(global: T, message: ApiMessage) {
|
||||
const { isSensitiveEnabled } = selectSettingsKeys(global);
|
||||
@ -46,19 +46,14 @@ export function selectIsMediaNsfw<T extends GlobalState>(global: T, message: Api
|
||||
}
|
||||
|
||||
export function selectMessageDownloadableMedia<T extends GlobalState>(global: T, message: MediaContainer) {
|
||||
const text = getMessageText(message);
|
||||
const firstEntity = text?.entities?.[0];
|
||||
const isSingleCustomEmoji = firstEntity
|
||||
&& text.entities?.length === 1
|
||||
&& firstEntity.type === ApiMessageEntityTypes.CustomEmoji
|
||||
&& firstEntity.offset === 0
|
||||
&& firstEntity.length === text.text.length;
|
||||
|
||||
const customEmoji = isSingleCustomEmoji ? selectCustomEmoji(global, firstEntity.documentId) : undefined;
|
||||
const singleEmoji = getMessageSingleRegularEmoji(message);
|
||||
const animatedEmoji = singleEmoji && selectAnimatedEmoji(global, singleEmoji);
|
||||
const animatedCustomEmojiId = getMessageSingleCustomEmoji(message);
|
||||
const customEmoji = animatedCustomEmojiId && selectCustomEmoji(global, animatedCustomEmojiId);
|
||||
|
||||
const webPage = selectWebPageFromMessage(global, message);
|
||||
return (
|
||||
customEmoji
|
||||
customEmoji || animatedEmoji
|
||||
|| getMessagePhoto(message)
|
||||
|| getMessageVideo(message)
|
||||
|| getMessageDocument(message)
|
||||
|
||||
@ -8,8 +8,9 @@ import { getSeconds } from './units';
|
||||
|
||||
const TIMESTAMP_RE = /\b(?:(\d{1,2}):)?([0-5]?\d):([0-5]\d)\b/g;
|
||||
|
||||
export function addTimestampEntities(apiText: ApiFormattedText): ApiFormattedText {
|
||||
const resultText: Required<ApiFormattedText> = {
|
||||
export function addTimestampEntities<T extends ApiFormattedText>(apiText: T): T {
|
||||
const resultText: Required<ApiFormattedText> & T = {
|
||||
...apiText,
|
||||
text: apiText.text,
|
||||
entities: apiText.entities?.filter((e) => e.type !== ApiMessageEntityTypes.Timestamp) || [],
|
||||
};
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user