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