From 5381c148e4f1f81a412534822ac1d1aff46195fe Mon Sep 17 00:00:00 2001 From: zubiden <19638254+zubiden@users.noreply.github.com> Date: Tue, 21 Jan 2025 18:20:54 +0100 Subject: [PATCH] Message: Show forward counter on view hover (#5447) --- src/api/gramjs/updates/mtpUpdateHandler.ts | 7 +++ src/assets/localization/fallback.strings | 12 ++++ .../middle/message/MessageMeta.scss | 2 + src/components/middle/message/MessageMeta.tsx | 61 +++++++++++++------ src/types/language.d.ts | 19 ++++++ 5 files changed, 82 insertions(+), 19 deletions(-) diff --git a/src/api/gramjs/updates/mtpUpdateHandler.ts b/src/api/gramjs/updates/mtpUpdateHandler.ts index ed8a6a8dc..a42ad1b5c 100644 --- a/src/api/gramjs/updates/mtpUpdateHandler.ts +++ b/src/api/gramjs/updates/mtpUpdateHandler.ts @@ -468,6 +468,13 @@ export function updater(update: Update) { id: update.id, message: { viewsCount: update.views }, }); + } else if (update instanceof GramJs.UpdateChannelMessageForwards) { + sendApiUpdate({ + '@type': 'updateMessage', + chatId: buildApiPeerId(update.channelId, 'channel'), + id: update.id, + message: { forwardsCount: update.forwards }, + }); // Chats } else if (update instanceof GramJs.UpdateReadHistoryInbox) { diff --git a/src/assets/localization/fallback.strings b/src/assets/localization/fallback.strings index 587f06d7a..da4acf9ea 100644 --- a/src/assets/localization/fallback.strings +++ b/src/assets/localization/fallback.strings @@ -732,6 +732,18 @@ "Reminders" = "Reminders"; "Messages_one" = "{count} message"; "Messages_other" = "{count} messages"; +"MessageTooltipForwards_one" = "Shares: {count}"; +"MessageTooltipForwards_other" = "Shares: {count}"; +"MessageTooltipViews_one" = "Views: {count}"; +"MessageTooltipViews_other" = "Views: {count}"; +"MessageTooltipReplies_one" = "Replies: {count}"; +"MessageTooltipReplies_other" = "Replies: {count}"; +"MessageTooltipEditedDate" = "Edited: {date}"; +"MessageTooltipForwardedDate" = "Original: {date}"; +"MessageMetaEdited" = "edited"; +"MessageMetaApproximate" = "approx."; +"MessageMetaImported" = "imported"; +"ImportedInfo" = "This message was imported from another app. We can't guarantee it's real."; "ScheduledMessagesEmptyPlaceholder" = "No scheduled messages here yet..."; "ConversationCloudStorageInfoTitle" = "Your Cloud Storage"; "ConversationClousStorageInfoDescription1" = "• Forward messages here to save them"; diff --git a/src/components/middle/message/MessageMeta.scss b/src/components/middle/message/MessageMeta.scss index 9cf0d9f36..14438f581 100644 --- a/src/components/middle/message/MessageMeta.scss +++ b/src/components/middle/message/MessageMeta.scss @@ -74,12 +74,14 @@ margin-left: 0.125rem; margin-right: 0.375rem; font-size: 1.125rem; + line-height: inherit; } .icon-reply-filled { margin-left: 0.125rem; margin-right: 0.375rem; font-size: 0.75rem; + line-height: inherit; } .has-solid-background & { diff --git a/src/components/middle/message/MessageMeta.tsx b/src/components/middle/message/MessageMeta.tsx index 4163e85cd..6cdbde99a 100644 --- a/src/components/middle/message/MessageMeta.tsx +++ b/src/components/middle/message/MessageMeta.tsx @@ -12,6 +12,7 @@ import { formatIntegerCompact } from '../../../util/textFormat'; import renderText from '../../common/helpers/renderText'; import useFlag from '../../../hooks/useFlag'; +import useLang from '../../../hooks/useLang'; import useOldLang from '../../../hooks/useOldLang'; import AnimatedCounter from '../../common/AnimatedCounter'; @@ -57,14 +58,19 @@ const MessageMeta: FC = ({ onOpenThread, }) => { const { showNotification } = getActions(); - const lang = useOldLang(); + const [isActivated, markActivated] = useFlag(); + const oldLang = useOldLang(); + const lang = useLang(); + function handleImportedClick(e: React.MouseEvent) { e.stopPropagation(); showNotification({ - message: lang('ImportedInfo'), + message: { + key: 'ImportedInfo', + }, }); } @@ -73,42 +79,59 @@ const MessageMeta: FC = ({ onOpenThread(); } - const title = useMemo(() => { + const dateTitle = useMemo(() => { if (!isActivated) return undefined; - const createDateTime = formatDateTimeToString(message.date * 1000, lang.code, undefined, lang.timeFormat); + const createDateTime = formatDateTimeToString(message.date * 1000, oldLang.code, undefined, oldLang.timeFormat); const editDateTime = message.isEdited - && formatDateTimeToString(message.editDate! * 1000, lang.code, undefined, lang.timeFormat); + && formatDateTimeToString(message.editDate! * 1000, oldLang.code, undefined, oldLang.timeFormat); const forwardedDateTime = message.forwardInfo && formatDateTimeToString( (message.forwardInfo.savedDate || message.forwardInfo.date) * 1000, - lang.code, + oldLang.code, undefined, - lang.timeFormat, + oldLang.timeFormat, ); let text = createDateTime; if (editDateTime) { text += '\n'; - text += lang('lng_edited_date').replace('{date}', editDateTime); + text += lang('MessageTooltipEditedDate', { date: editDateTime }); } if (forwardedDateTime) { text += '\n'; - text += lang('lng_forwarded_date').replace('{date}', forwardedDateTime); + text += lang('MessageTooltipForwardedDate', { date: forwardedDateTime }); } return text; // We need to listen to timeformat change // eslint-disable-next-line react-hooks-static-deps/exhaustive-deps - }, [isActivated, lang, message, lang.timeFormat]); + }, [isActivated, oldLang, message, oldLang.timeFormat]); + + const viewsTitle = useMemo(() => { + if (!message.viewsCount) return undefined; + let text = lang('MessageTooltipViews', { count: message.viewsCount }, { pluralValue: message.viewsCount }); + if (message.forwardsCount) { + text += '\n'; + text += lang('MessageTooltipForwards', { count: message.forwardsCount }, { pluralValue: message.forwardsCount }); + } + + return text; + }, [lang, message.forwardsCount, message.viewsCount]); + + const repliesTitle = useMemo(() => { + const count = repliesThreadInfo?.messagesCount; + if (!count) return undefined; + return lang('MessageTooltipReplies', { count }, { pluralValue: count }); + }, [lang, repliesThreadInfo]); const date = useMemo(() => { - const time = formatTime(lang, message.date * 1000); + const time = formatTime(oldLang, message.date * 1000); if (!withFullDate) { return time; } - return formatPastTimeShort(lang, (message.forwardInfo?.date || message.date) * 1000, true); - }, [lang, message.date, message.forwardInfo?.date, withFullDate]); + return formatPastTimeShort(oldLang, (message.forwardInfo?.date || message.date) * 1000, true); + }, [oldLang, message.date, message.forwardInfo?.date, withFullDate]); const fullClassName = buildClassName( 'MessageMeta', @@ -133,14 +156,14 @@ const MessageMeta: FC = ({ )} {Boolean(message.viewsCount) && ( <> - + {formatIntegerCompact(message.viewsCount!)} )} {!noReplies && Boolean(repliesThreadInfo?.messagesCount) && ( - + @@ -153,17 +176,17 @@ const MessageMeta: FC = ({ {signature && ( {renderText(signature)} )} - + {message.forwardInfo?.isImported && ( <> {formatDateTimeToString(message.forwardInfo.date * 1000, lang.code, true)} - {lang('ImportedMessage')} + {lang('MessageMetaImported')} )} - {message.isEdited && `${lang('EditedMessage')} `} - {message.isVideoProcessingPending && `${lang('lng_approximate')} `} + {message.isEdited && `${lang('MessageMetaEdited')} `} + {message.isVideoProcessingPending && `${lang('MessageMetaApproximate')} `} {date} {outgoingStatus && ( diff --git a/src/types/language.d.ts b/src/types/language.d.ts index d711708d1..2a54ad25b 100644 --- a/src/types/language.d.ts +++ b/src/types/language.d.ts @@ -627,6 +627,10 @@ export interface LangPair { 'ContextCopySelectedItems': undefined; 'EditAdminGroupDeleteMessages': undefined; 'Reminders': undefined; + 'MessageMetaEdited': undefined; + 'MessageMetaApproximate': undefined; + 'MessageMetaImported': undefined; + 'ImportedInfo': undefined; 'ScheduledMessagesEmptyPlaceholder': undefined; 'ConversationCloudStorageInfoTitle': undefined; 'ConversationClousStorageInfoDescription1': undefined; @@ -1396,6 +1400,12 @@ export interface LangPairWithVariables { 'MessageScheduledOn': { 'date': V; }; + 'MessageTooltipEditedDate': { + 'date': V; + }; + 'MessageTooltipForwardedDate': { + 'date': V; + }; 'EmptyGroupInfoLine1': { 'count': V; }; @@ -1761,6 +1771,15 @@ export interface LangPairPluralWithVariables { 'Messages': { 'count': V; }; + 'MessageTooltipForwards': { + 'count': V; + }; + 'MessageTooltipViews': { + 'count': V; + }; + 'MessageTooltipReplies': { + 'count': V; + }; 'Hours': { 'count': V; };