Message: Show forward counter on view hover (#5447)
This commit is contained in:
parent
9b57bd9e21
commit
5381c148e4
@ -468,6 +468,13 @@ export function updater(update: Update) {
|
|||||||
id: update.id,
|
id: update.id,
|
||||||
message: { viewsCount: update.views },
|
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
|
// Chats
|
||||||
} else if (update instanceof GramJs.UpdateReadHistoryInbox) {
|
} else if (update instanceof GramJs.UpdateReadHistoryInbox) {
|
||||||
|
|||||||
@ -732,6 +732,18 @@
|
|||||||
"Reminders" = "Reminders";
|
"Reminders" = "Reminders";
|
||||||
"Messages_one" = "{count} message";
|
"Messages_one" = "{count} message";
|
||||||
"Messages_other" = "{count} messages";
|
"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...";
|
"ScheduledMessagesEmptyPlaceholder" = "No scheduled messages here yet...";
|
||||||
"ConversationCloudStorageInfoTitle" = "Your Cloud Storage";
|
"ConversationCloudStorageInfoTitle" = "Your Cloud Storage";
|
||||||
"ConversationClousStorageInfoDescription1" = "• Forward messages here to save them";
|
"ConversationClousStorageInfoDescription1" = "• Forward messages here to save them";
|
||||||
|
|||||||
@ -74,12 +74,14 @@
|
|||||||
margin-left: 0.125rem;
|
margin-left: 0.125rem;
|
||||||
margin-right: 0.375rem;
|
margin-right: 0.375rem;
|
||||||
font-size: 1.125rem;
|
font-size: 1.125rem;
|
||||||
|
line-height: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-reply-filled {
|
.icon-reply-filled {
|
||||||
margin-left: 0.125rem;
|
margin-left: 0.125rem;
|
||||||
margin-right: 0.375rem;
|
margin-right: 0.375rem;
|
||||||
font-size: 0.75rem;
|
font-size: 0.75rem;
|
||||||
|
line-height: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
.has-solid-background & {
|
.has-solid-background & {
|
||||||
|
|||||||
@ -12,6 +12,7 @@ import { formatIntegerCompact } from '../../../util/textFormat';
|
|||||||
import renderText from '../../common/helpers/renderText';
|
import renderText from '../../common/helpers/renderText';
|
||||||
|
|
||||||
import useFlag from '../../../hooks/useFlag';
|
import useFlag from '../../../hooks/useFlag';
|
||||||
|
import useLang from '../../../hooks/useLang';
|
||||||
import useOldLang from '../../../hooks/useOldLang';
|
import useOldLang from '../../../hooks/useOldLang';
|
||||||
|
|
||||||
import AnimatedCounter from '../../common/AnimatedCounter';
|
import AnimatedCounter from '../../common/AnimatedCounter';
|
||||||
@ -57,14 +58,19 @@ const MessageMeta: FC<OwnProps> = ({
|
|||||||
onOpenThread,
|
onOpenThread,
|
||||||
}) => {
|
}) => {
|
||||||
const { showNotification } = getActions();
|
const { showNotification } = getActions();
|
||||||
const lang = useOldLang();
|
|
||||||
const [isActivated, markActivated] = useFlag();
|
const [isActivated, markActivated] = useFlag();
|
||||||
|
|
||||||
|
const oldLang = useOldLang();
|
||||||
|
const lang = useLang();
|
||||||
|
|
||||||
function handleImportedClick(e: React.MouseEvent) {
|
function handleImportedClick(e: React.MouseEvent) {
|
||||||
e.stopPropagation();
|
e.stopPropagation();
|
||||||
|
|
||||||
showNotification({
|
showNotification({
|
||||||
message: lang('ImportedInfo'),
|
message: {
|
||||||
|
key: 'ImportedInfo',
|
||||||
|
},
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,42 +79,59 @@ const MessageMeta: FC<OwnProps> = ({
|
|||||||
onOpenThread();
|
onOpenThread();
|
||||||
}
|
}
|
||||||
|
|
||||||
const title = useMemo(() => {
|
const dateTitle = useMemo(() => {
|
||||||
if (!isActivated) return undefined;
|
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
|
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
|
const forwardedDateTime = message.forwardInfo
|
||||||
&& formatDateTimeToString(
|
&& formatDateTimeToString(
|
||||||
(message.forwardInfo.savedDate || message.forwardInfo.date) * 1000,
|
(message.forwardInfo.savedDate || message.forwardInfo.date) * 1000,
|
||||||
lang.code,
|
oldLang.code,
|
||||||
undefined,
|
undefined,
|
||||||
lang.timeFormat,
|
oldLang.timeFormat,
|
||||||
);
|
);
|
||||||
|
|
||||||
let text = createDateTime;
|
let text = createDateTime;
|
||||||
if (editDateTime) {
|
if (editDateTime) {
|
||||||
text += '\n';
|
text += '\n';
|
||||||
text += lang('lng_edited_date').replace('{date}', editDateTime);
|
text += lang('MessageTooltipEditedDate', { date: editDateTime });
|
||||||
}
|
}
|
||||||
if (forwardedDateTime) {
|
if (forwardedDateTime) {
|
||||||
text += '\n';
|
text += '\n';
|
||||||
text += lang('lng_forwarded_date').replace('{date}', forwardedDateTime);
|
text += lang('MessageTooltipForwardedDate', { date: forwardedDateTime });
|
||||||
}
|
}
|
||||||
|
|
||||||
return text;
|
return text;
|
||||||
// We need to listen to timeformat change
|
// We need to listen to timeformat change
|
||||||
// eslint-disable-next-line react-hooks-static-deps/exhaustive-deps
|
// 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 date = useMemo(() => {
|
||||||
const time = formatTime(lang, message.date * 1000);
|
const time = formatTime(oldLang, message.date * 1000);
|
||||||
if (!withFullDate) {
|
if (!withFullDate) {
|
||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
return formatPastTimeShort(lang, (message.forwardInfo?.date || message.date) * 1000, true);
|
return formatPastTimeShort(oldLang, (message.forwardInfo?.date || message.date) * 1000, true);
|
||||||
}, [lang, message.date, message.forwardInfo?.date, withFullDate]);
|
}, [oldLang, message.date, message.forwardInfo?.date, withFullDate]);
|
||||||
|
|
||||||
const fullClassName = buildClassName(
|
const fullClassName = buildClassName(
|
||||||
'MessageMeta',
|
'MessageMeta',
|
||||||
@ -133,14 +156,14 @@ const MessageMeta: FC<OwnProps> = ({
|
|||||||
)}
|
)}
|
||||||
{Boolean(message.viewsCount) && (
|
{Boolean(message.viewsCount) && (
|
||||||
<>
|
<>
|
||||||
<span className="message-views">
|
<span className="message-views" title={viewsTitle}>
|
||||||
{formatIntegerCompact(message.viewsCount!)}
|
{formatIntegerCompact(message.viewsCount!)}
|
||||||
</span>
|
</span>
|
||||||
<Icon name="channelviews" />
|
<Icon name="channelviews" />
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{!noReplies && Boolean(repliesThreadInfo?.messagesCount) && (
|
{!noReplies && Boolean(repliesThreadInfo?.messagesCount) && (
|
||||||
<span onClick={handleOpenThread} className="message-replies-wrapper">
|
<span onClick={handleOpenThread} className="message-replies-wrapper" title={repliesTitle}>
|
||||||
<span className="message-replies">
|
<span className="message-replies">
|
||||||
<AnimatedCounter text={formatIntegerCompact(repliesThreadInfo!.messagesCount!)} />
|
<AnimatedCounter text={formatIntegerCompact(repliesThreadInfo!.messagesCount!)} />
|
||||||
</span>
|
</span>
|
||||||
@ -153,17 +176,17 @@ const MessageMeta: FC<OwnProps> = ({
|
|||||||
{signature && (
|
{signature && (
|
||||||
<span className="message-signature">{renderText(signature)}</span>
|
<span className="message-signature">{renderText(signature)}</span>
|
||||||
)}
|
)}
|
||||||
<span className="message-time" title={title} onMouseEnter={markActivated}>
|
<span className="message-time" title={dateTitle} onMouseEnter={markActivated}>
|
||||||
{message.forwardInfo?.isImported && (
|
{message.forwardInfo?.isImported && (
|
||||||
<>
|
<>
|
||||||
<span className="message-imported" onClick={handleImportedClick}>
|
<span className="message-imported" onClick={handleImportedClick}>
|
||||||
{formatDateTimeToString(message.forwardInfo.date * 1000, lang.code, true)}
|
{formatDateTimeToString(message.forwardInfo.date * 1000, lang.code, true)}
|
||||||
</span>
|
</span>
|
||||||
<span className="message-imported" onClick={handleImportedClick}>{lang('ImportedMessage')}</span>
|
<span className="message-imported" onClick={handleImportedClick}>{lang('MessageMetaImported')}</span>
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{message.isEdited && `${lang('EditedMessage')} `}
|
{message.isEdited && `${lang('MessageMetaEdited')} `}
|
||||||
{message.isVideoProcessingPending && `${lang('lng_approximate')} `}
|
{message.isVideoProcessingPending && `${lang('MessageMetaApproximate')} `}
|
||||||
{date}
|
{date}
|
||||||
</span>
|
</span>
|
||||||
{outgoingStatus && (
|
{outgoingStatus && (
|
||||||
|
|||||||
19
src/types/language.d.ts
vendored
19
src/types/language.d.ts
vendored
@ -627,6 +627,10 @@ export interface LangPair {
|
|||||||
'ContextCopySelectedItems': undefined;
|
'ContextCopySelectedItems': undefined;
|
||||||
'EditAdminGroupDeleteMessages': undefined;
|
'EditAdminGroupDeleteMessages': undefined;
|
||||||
'Reminders': undefined;
|
'Reminders': undefined;
|
||||||
|
'MessageMetaEdited': undefined;
|
||||||
|
'MessageMetaApproximate': undefined;
|
||||||
|
'MessageMetaImported': undefined;
|
||||||
|
'ImportedInfo': undefined;
|
||||||
'ScheduledMessagesEmptyPlaceholder': undefined;
|
'ScheduledMessagesEmptyPlaceholder': undefined;
|
||||||
'ConversationCloudStorageInfoTitle': undefined;
|
'ConversationCloudStorageInfoTitle': undefined;
|
||||||
'ConversationClousStorageInfoDescription1': undefined;
|
'ConversationClousStorageInfoDescription1': undefined;
|
||||||
@ -1396,6 +1400,12 @@ export interface LangPairWithVariables<V extends unknown = LangVariable> {
|
|||||||
'MessageScheduledOn': {
|
'MessageScheduledOn': {
|
||||||
'date': V;
|
'date': V;
|
||||||
};
|
};
|
||||||
|
'MessageTooltipEditedDate': {
|
||||||
|
'date': V;
|
||||||
|
};
|
||||||
|
'MessageTooltipForwardedDate': {
|
||||||
|
'date': V;
|
||||||
|
};
|
||||||
'EmptyGroupInfoLine1': {
|
'EmptyGroupInfoLine1': {
|
||||||
'count': V;
|
'count': V;
|
||||||
};
|
};
|
||||||
@ -1761,6 +1771,15 @@ export interface LangPairPluralWithVariables<V extends unknown = LangVariable> {
|
|||||||
'Messages': {
|
'Messages': {
|
||||||
'count': V;
|
'count': V;
|
||||||
};
|
};
|
||||||
|
'MessageTooltipForwards': {
|
||||||
|
'count': V;
|
||||||
|
};
|
||||||
|
'MessageTooltipViews': {
|
||||||
|
'count': V;
|
||||||
|
};
|
||||||
|
'MessageTooltipReplies': {
|
||||||
|
'count': V;
|
||||||
|
};
|
||||||
'Hours': {
|
'Hours': {
|
||||||
'count': V;
|
'count': V;
|
||||||
};
|
};
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user