MessageMeta: Display signature in more places (#4234)
This commit is contained in:
parent
2bf38d0726
commit
9a0c0e10dd
@ -273,7 +273,7 @@ function buildApiMessageForwardInfo(fwdFrom: GramJs.MessageFwdHeader, isChatWith
|
|||||||
isLinkedChannelPost: Boolean(fwdFrom.channelPost && savedFromPeerId && !isChatWithSelf),
|
isLinkedChannelPost: Boolean(fwdFrom.channelPost && savedFromPeerId && !isChatWithSelf),
|
||||||
savedFromPeerId,
|
savedFromPeerId,
|
||||||
fromId,
|
fromId,
|
||||||
fromChatId: savedFromPeerId || fromId,
|
fromChatId: fromId || savedFromPeerId,
|
||||||
fromMessageId: fwdFrom.savedFromMsgId || fwdFrom.channelPost,
|
fromMessageId: fwdFrom.savedFromMsgId || fwdFrom.channelPost,
|
||||||
hiddenUserName: fwdFrom.fromName,
|
hiddenUserName: fwdFrom.fromName,
|
||||||
postAuthorTitle: fwdFrom.postAuthor,
|
postAuthorTitle: fwdFrom.postAuthor,
|
||||||
|
|||||||
@ -249,4 +249,8 @@
|
|||||||
&.forum {
|
&.forum {
|
||||||
--radius: var(--border-radius-forum-avatar);
|
--radius: var(--border-radius-forum-avatar);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
&.hidden-user {
|
||||||
|
--color-user: var(--color-deleted-account);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -211,6 +211,7 @@ const Avatar: FC<OwnProps> = ({
|
|||||||
`Avatar size-${size}`,
|
`Avatar size-${size}`,
|
||||||
className,
|
className,
|
||||||
getPeerColorClass(peer),
|
getPeerColorClass(peer),
|
||||||
|
!peer && text && 'hidden-user',
|
||||||
isSavedMessages && 'saved-messages',
|
isSavedMessages && 'saved-messages',
|
||||||
isAnonymousForwards && 'anonymous-forwards',
|
isAnonymousForwards && 'anonymous-forwards',
|
||||||
isDeleted && 'deleted-account',
|
isDeleted && 'deleted-account',
|
||||||
|
|||||||
@ -1,22 +0,0 @@
|
|||||||
import type { RefObject } from 'react';
|
|
||||||
import { useLayoutEffect } from '../../../lib/teact/teact';
|
|
||||||
|
|
||||||
import { requestForcedReflow } from '../../../lib/fasterdom/fasterdom';
|
|
||||||
|
|
||||||
export default function useAuthorWidth(
|
|
||||||
containerRef: RefObject<HTMLDivElement>,
|
|
||||||
signature?: string,
|
|
||||||
) {
|
|
||||||
useLayoutEffect(() => {
|
|
||||||
if (!signature) return;
|
|
||||||
|
|
||||||
requestForcedReflow(() => {
|
|
||||||
const width = containerRef.current!.querySelector<HTMLDivElement>('.message-signature')?.offsetWidth;
|
|
||||||
if (!width) return undefined;
|
|
||||||
|
|
||||||
return () => {
|
|
||||||
containerRef.current!.style.setProperty('--meta-safe-author-width', `${width}px`);
|
|
||||||
};
|
|
||||||
});
|
|
||||||
}, [containerRef, signature]);
|
|
||||||
}
|
|
||||||
@ -20,12 +20,6 @@
|
|||||||
--accent-color: var(--color-primary);
|
--accent-color: var(--color-primary);
|
||||||
--accent-shade-color: var(--color-primary-shade);
|
--accent-shade-color: var(--color-primary-shade);
|
||||||
--secondary-color: var(--color-text-secondary);
|
--secondary-color: var(--color-text-secondary);
|
||||||
--meta-safe-area-base: 2.25rem;
|
|
||||||
--meta-safe-author-width: 0px;
|
|
||||||
--meta-safe-area-extra-width: 0px;
|
|
||||||
--meta-safe-area-size: calc(
|
|
||||||
var(--meta-safe-area-base) + var(--meta-safe-author-width) + var(--meta-safe-area-extra-width)
|
|
||||||
);
|
|
||||||
--color-voice-transcribe: var(--color-voice-transcribe-button);
|
--color-voice-transcribe: var(--color-voice-transcribe-button);
|
||||||
--thumbs-background: var(--color-background);
|
--thumbs-background: var(--color-background);
|
||||||
--deleting-translate-x: -50%;
|
--deleting-translate-x: -50%;
|
||||||
@ -200,7 +194,6 @@
|
|||||||
--color-code: var(--color-code-own);
|
--color-code: var(--color-code-own);
|
||||||
--color-code-bg: var(--color-code-own-bg);
|
--color-code-bg: var(--color-code-own-bg);
|
||||||
--color-links: var(--color-own-links);
|
--color-links: var(--color-own-links);
|
||||||
--meta-safe-area-base: 3.5rem;
|
|
||||||
--deleting-translate-x: 50%;
|
--deleting-translate-x: 50%;
|
||||||
--color-text-green: var(--color-accent-own);
|
--color-text-green: var(--color-accent-own);
|
||||||
--color-voice-transcribe: var(--color-voice-transcribe-button-own);
|
--color-voice-transcribe: var(--color-voice-transcribe-button-own);
|
||||||
@ -336,26 +329,6 @@
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
&.has-views {
|
|
||||||
--meta-safe-area-extra-width: 4rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
&.was-edited {
|
|
||||||
--meta-safe-area-extra-width: 2.5rem;
|
|
||||||
|
|
||||||
&.has-views {
|
|
||||||
--meta-safe-area-extra-width: 7.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
html[lang="ru"] & {
|
|
||||||
--meta-safe-area-extra-width: 3.5rem;
|
|
||||||
|
|
||||||
&.has-views {
|
|
||||||
--meta-safe-area-extra-width: 8.5rem;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
.select-mode-active & {
|
.select-mode-active & {
|
||||||
cursor: var(--custom-cursor, pointer);
|
cursor: var(--custom-cursor, pointer);
|
||||||
|
|
||||||
|
|||||||
@ -34,7 +34,6 @@ import { AudioOrigin } from '../../../types';
|
|||||||
import { EMOJI_STATUS_LOOP_LIMIT, GENERAL_TOPIC_ID } from '../../../config';
|
import { EMOJI_STATUS_LOOP_LIMIT, GENERAL_TOPIC_ID } from '../../../config';
|
||||||
import {
|
import {
|
||||||
areReactionsEmpty,
|
areReactionsEmpty,
|
||||||
getIsSavedDialog,
|
|
||||||
getMessageContent,
|
getMessageContent,
|
||||||
getMessageCustomShape,
|
getMessageCustomShape,
|
||||||
getMessageHtmlId,
|
getMessageHtmlId,
|
||||||
@ -129,7 +128,6 @@ import useResizeObserver from '../../../hooks/useResizeObserver';
|
|||||||
import useShowTransition from '../../../hooks/useShowTransition';
|
import useShowTransition from '../../../hooks/useShowTransition';
|
||||||
import useTextLanguage from '../../../hooks/useTextLanguage';
|
import useTextLanguage from '../../../hooks/useTextLanguage';
|
||||||
import useThrottledCallback from '../../../hooks/useThrottledCallback';
|
import useThrottledCallback from '../../../hooks/useThrottledCallback';
|
||||||
import useAuthorWidth from '../hooks/useAuthorWidth';
|
|
||||||
import useDetectChatLanguage from './hooks/useDetectChatLanguage';
|
import useDetectChatLanguage from './hooks/useDetectChatLanguage';
|
||||||
import useFocusMessage from './hooks/useFocusMessage';
|
import useFocusMessage from './hooks/useFocusMessage';
|
||||||
import useInnerHandlers from './hooks/useInnerHandlers';
|
import useInnerHandlers from './hooks/useInnerHandlers';
|
||||||
@ -279,7 +277,6 @@ type StateProps = {
|
|||||||
isConnected: boolean;
|
isConnected: boolean;
|
||||||
isLoadingComments?: boolean;
|
isLoadingComments?: boolean;
|
||||||
shouldWarnAboutSvg?: boolean;
|
shouldWarnAboutSvg?: boolean;
|
||||||
isInSavedDialog?: boolean;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type MetaPosition =
|
type MetaPosition =
|
||||||
@ -394,7 +391,6 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
isConnected,
|
isConnected,
|
||||||
getIsMessageListReady,
|
getIsMessageListReady,
|
||||||
shouldWarnAboutSvg,
|
shouldWarnAboutSvg,
|
||||||
isInSavedDialog,
|
|
||||||
onPinnedIntersectionChange,
|
onPinnedIntersectionChange,
|
||||||
}) => {
|
}) => {
|
||||||
const {
|
const {
|
||||||
@ -749,9 +745,8 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
);
|
);
|
||||||
|
|
||||||
const signature = (isChannel && message.postAuthorTitle)
|
const signature = (isChannel && message.postAuthorTitle)
|
||||||
|| (!asForwarded && forwardInfo?.postAuthorTitle)
|
|| ((asForwarded || isChatWithSelf) && forwardInfo?.postAuthorTitle)
|
||||||
|| undefined;
|
|| undefined;
|
||||||
useAuthorWidth(ref, signature);
|
|
||||||
|
|
||||||
const shouldFocusOnResize = isLastInList;
|
const shouldFocusOnResize = isLastInList;
|
||||||
|
|
||||||
@ -924,7 +919,7 @@ const Message: FC<OwnProps & StateProps> = ({
|
|||||||
<MessageMeta
|
<MessageMeta
|
||||||
message={message}
|
message={message}
|
||||||
isPinned={isPinned}
|
isPinned={isPinned}
|
||||||
isInSavedDialog={isInSavedDialog}
|
withFullDate={isChatWithSelf && !isOwn}
|
||||||
noReplies={noReplies}
|
noReplies={noReplies}
|
||||||
repliesThreadInfo={repliesThreadInfo}
|
repliesThreadInfo={repliesThreadInfo}
|
||||||
outgoingStatus={outgoingStatus}
|
outgoingStatus={outgoingStatus}
|
||||||
@ -1567,8 +1562,6 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
|
|
||||||
const hasActiveReactions = Boolean(reactionMessage && activeReactions[getMessageKey(reactionMessage)]?.length);
|
const hasActiveReactions = Boolean(reactionMessage && activeReactions[getMessageKey(reactionMessage)]?.length);
|
||||||
|
|
||||||
const isInSavedDialog = getIsSavedDialog(chatId, threadId, global.currentUserId);
|
|
||||||
|
|
||||||
return {
|
return {
|
||||||
theme: selectTheme(global),
|
theme: selectTheme(global),
|
||||||
forceSenderName,
|
forceSenderName,
|
||||||
@ -1637,7 +1630,6 @@ export default memo(withGlobal<OwnProps>(
|
|||||||
withStickerEffects: selectPerformanceSettingsValue(global, 'stickerEffects'),
|
withStickerEffects: selectPerformanceSettingsValue(global, 'stickerEffects'),
|
||||||
webPageStory,
|
webPageStory,
|
||||||
isConnected,
|
isConnected,
|
||||||
isInSavedDialog,
|
|
||||||
isLoadingComments: repliesThreadInfo?.isCommentsInfo
|
isLoadingComments: repliesThreadInfo?.isCommentsInfo
|
||||||
&& loadingThread?.loadingChatId === repliesThreadInfo?.originChannelId
|
&& loadingThread?.loadingChatId === repliesThreadInfo?.originChannelId
|
||||||
&& loadingThread?.loadingMessageId === repliesThreadInfo?.originMessageId,
|
&& loadingThread?.loadingMessageId === repliesThreadInfo?.originMessageId,
|
||||||
|
|||||||
@ -10,7 +10,7 @@
|
|||||||
padding: 0 0.25rem;
|
padding: 0 0.25rem;
|
||||||
color: white;
|
color: white;
|
||||||
cursor: var(--custom-cursor, pointer);
|
cursor: var(--custom-cursor, pointer);
|
||||||
max-width: 100%;
|
max-width: calc(100% - 0.5rem);
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
|
||||||
.message-time,
|
.message-time,
|
||||||
@ -67,8 +67,6 @@
|
|||||||
margin-left: 0.125rem;
|
margin-left: 0.125rem;
|
||||||
margin-right: 0.375rem;
|
margin-right: 0.375rem;
|
||||||
font-size: 1.125rem;
|
font-size: 1.125rem;
|
||||||
position: relative;
|
|
||||||
top: -0.0625rem;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.icon-reply-filled {
|
.icon-reply-filled {
|
||||||
@ -132,6 +130,7 @@
|
|||||||
.is-forwarded.media:not(.text) & {
|
.is-forwarded.media:not(.text) & {
|
||||||
bottom: 0.9375rem;
|
bottom: 0.9375rem;
|
||||||
right: 0.8125rem;
|
right: 0.8125rem;
|
||||||
|
max-width: calc(100% - 2.25rem);
|
||||||
}
|
}
|
||||||
|
|
||||||
.Message.own .has-solid-background & {
|
.Message.own .has-solid-background & {
|
||||||
@ -142,6 +141,7 @@
|
|||||||
margin-left: -0.1875rem;
|
margin-left: -0.1875rem;
|
||||||
font-size: 1.1875rem;
|
font-size: 1.1875rem;
|
||||||
border-radius: 0.625rem;
|
border-radius: 0.625rem;
|
||||||
|
flex-shrink: 0;
|
||||||
|
|
||||||
.Message.own & {
|
.Message.own & {
|
||||||
color: var(--color-accent-own);
|
color: var(--color-accent-own);
|
||||||
|
|||||||
@ -7,7 +7,7 @@ import type {
|
|||||||
} from '../../../api/types';
|
} from '../../../api/types';
|
||||||
|
|
||||||
import buildClassName from '../../../util/buildClassName';
|
import buildClassName from '../../../util/buildClassName';
|
||||||
import { formatDateTimeToString, formatTime } from '../../../util/dateFormat';
|
import { formatDateTimeToString, formatPastTimeShort, formatTime } from '../../../util/dateFormat';
|
||||||
import { formatIntegerCompact } from '../../../util/textFormat';
|
import { formatIntegerCompact } from '../../../util/textFormat';
|
||||||
import renderText from '../../common/helpers/renderText';
|
import renderText from '../../common/helpers/renderText';
|
||||||
|
|
||||||
@ -29,7 +29,7 @@ type OwnProps = {
|
|||||||
repliesThreadInfo?: ApiThreadInfo;
|
repliesThreadInfo?: ApiThreadInfo;
|
||||||
isTranslated?: boolean;
|
isTranslated?: boolean;
|
||||||
isPinned?: boolean;
|
isPinned?: boolean;
|
||||||
isInSavedDialog?: boolean;
|
withFullDate?: boolean;
|
||||||
onClick: (e: React.MouseEvent<HTMLDivElement>) => void;
|
onClick: (e: React.MouseEvent<HTMLDivElement>) => void;
|
||||||
onTranslationClick: (e: React.MouseEvent<HTMLDivElement>) => void;
|
onTranslationClick: (e: React.MouseEvent<HTMLDivElement>) => void;
|
||||||
renderQuickReactionButton?: () => TeactNode | undefined;
|
renderQuickReactionButton?: () => TeactNode | undefined;
|
||||||
@ -46,7 +46,7 @@ const MessageMeta: FC<OwnProps> = ({
|
|||||||
noReplies,
|
noReplies,
|
||||||
isTranslated,
|
isTranslated,
|
||||||
isPinned,
|
isPinned,
|
||||||
isInSavedDialog,
|
withFullDate,
|
||||||
onClick,
|
onClick,
|
||||||
onTranslationClick,
|
onTranslationClick,
|
||||||
onOpenThread,
|
onOpenThread,
|
||||||
@ -96,6 +96,15 @@ const MessageMeta: FC<OwnProps> = ({
|
|||||||
// 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, lang, message, lang.timeFormat]);
|
||||||
|
|
||||||
|
const date = useMemo(() => {
|
||||||
|
const time = formatTime(lang, message.date * 1000);
|
||||||
|
if (!withFullDate) {
|
||||||
|
return time;
|
||||||
|
}
|
||||||
|
|
||||||
|
return formatPastTimeShort(lang, (message.forwardInfo?.date || message.date) * 1000, true);
|
||||||
|
}, [lang, message.date, message.forwardInfo?.date, withFullDate]);
|
||||||
|
|
||||||
const fullClassName = buildClassName(
|
const fullClassName = buildClassName(
|
||||||
'MessageMeta',
|
'MessageMeta',
|
||||||
withReactionOffset && 'reactions-offset',
|
withReactionOffset && 'reactions-offset',
|
||||||
@ -144,9 +153,7 @@ const MessageMeta: FC<OwnProps> = ({
|
|||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
{message.isEdited && `${lang('EditedMessage')} `}
|
{message.isEdited && `${lang('EditedMessage')} `}
|
||||||
{isInSavedDialog
|
{date}
|
||||||
? formatDateTimeToString((message.forwardInfo?.date || message.date) * 1000, lang.code, true)
|
|
||||||
: formatTime(lang, message.date * 1000)}
|
|
||||||
</span>
|
</span>
|
||||||
{outgoingStatus && (
|
{outgoingStatus && (
|
||||||
<MessageOutgoingStatus status={outgoingStatus} />
|
<MessageOutgoingStatus status={outgoingStatus} />
|
||||||
|
|||||||
@ -102,7 +102,7 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.message-content:not(.has-reactions) & {
|
.message-content:not(.has-reactions) & {
|
||||||
margin-bottom: calc(var(--message-meta-height) + 0.375rem) !important;
|
margin-bottom: calc(var(--message-meta-height)) !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
&.with-square-photo .WebPage--content {
|
&.with-square-photo .WebPage--content {
|
||||||
|
|||||||
@ -364,13 +364,6 @@
|
|||||||
|
|
||||||
&.has-solid-background {
|
&.has-solid-background {
|
||||||
padding: 0.3125rem 0.5rem 0.375rem;
|
padding: 0.3125rem 0.5rem 0.375rem;
|
||||||
|
|
||||||
.forwarded-message > .text-content:not(.with-meta):last-child::after {
|
|
||||||
content: "";
|
|
||||||
display: inline-block;
|
|
||||||
width: var(--meta-safe-area-size);
|
|
||||||
height: 1rem;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
body.is-ios &.has-solid-background {
|
body.is-ios &.has-solid-background {
|
||||||
|
|||||||
@ -51,7 +51,7 @@ export const CUSTOM_EMOJI_PREVIEW_CACHE_DISABLED = false;
|
|||||||
export const CUSTOM_EMOJI_PREVIEW_CACHE_NAME = 'tt-custom-emoji-preview';
|
export const CUSTOM_EMOJI_PREVIEW_CACHE_NAME = 'tt-custom-emoji-preview';
|
||||||
export const MEDIA_CACHE_MAX_BYTES = 512 * 1024; // 512 KB
|
export const MEDIA_CACHE_MAX_BYTES = 512 * 1024; // 512 KB
|
||||||
export const CUSTOM_BG_CACHE_NAME = 'tt-custom-bg';
|
export const CUSTOM_BG_CACHE_NAME = 'tt-custom-bg';
|
||||||
export const LANG_CACHE_NAME = 'tt-lang-packs-v30';
|
export const LANG_CACHE_NAME = 'tt-lang-packs-v31';
|
||||||
export const ASSET_CACHE_NAME = 'tt-assets';
|
export const ASSET_CACHE_NAME = 'tt-assets';
|
||||||
export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500];
|
export const AUTODOWNLOAD_FILESIZE_MB_LIMITS = [1, 5, 10, 50, 100, 500];
|
||||||
export const DATA_BROADCAST_CHANNEL_NAME = 'tt-global';
|
export const DATA_BROADCAST_CHANNEL_NAME = 'tt-global';
|
||||||
|
|||||||
@ -53,23 +53,27 @@ export function formatTime(lang: LangFn, datetime: number | Date) {
|
|||||||
return `${String(hours).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}${marker}`;
|
return `${String(hours).padStart(2, '0')}:${String(date.getMinutes()).padStart(2, '0')}${marker}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatPastTimeShort(lang: LangFn, datetime: number | Date) {
|
export function formatPastTimeShort(lang: LangFn, datetime: number | Date, alwaysShowTime = false) {
|
||||||
const date = typeof datetime === 'number' ? new Date(datetime) : datetime;
|
const date = typeof datetime === 'number' ? new Date(datetime) : datetime;
|
||||||
|
|
||||||
|
const time = formatTime(lang, date);
|
||||||
|
|
||||||
const today = getDayStart(new Date());
|
const today = getDayStart(new Date());
|
||||||
if (date >= today) {
|
if (date >= today) {
|
||||||
return formatTime(lang, date);
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
const weekAgo = new Date(today);
|
const weekAgo = new Date(today);
|
||||||
weekAgo.setDate(today.getDate() - 7);
|
weekAgo.setDate(today.getDate() - 7);
|
||||||
if (date >= weekAgo) {
|
if (date >= weekAgo) {
|
||||||
return lang(`Weekday.Short${WEEKDAYS_FULL[date.getDay()]}`);
|
const weekday = lang(`Weekday.Short${WEEKDAYS_FULL[date.getDay()]}`);
|
||||||
|
return alwaysShowTime ? lang('FullDateTimeFormat', [weekday, time]) : weekday;
|
||||||
}
|
}
|
||||||
|
|
||||||
const noYear = date.getFullYear() === today.getFullYear();
|
const noYear = date.getFullYear() === today.getFullYear();
|
||||||
|
|
||||||
return formatDateToString(date, lang.code, noYear);
|
const formattedDate = formatDateToString(date, lang.code, noYear);
|
||||||
|
return alwaysShowTime ? lang('FullDateTimeFormat', [formattedDate, time]) : formattedDate;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function formatFullDate(lang: LangFn, datetime: number | Date) {
|
export function formatFullDate(lang: LangFn, datetime: number | Date) {
|
||||||
|
|||||||
@ -509,4 +509,5 @@ export default {
|
|||||||
'Video.Unsupported.Mobile': 'Unfortunately, this video can\'t be played on Telegram Web. Try opening it with our **mobile app** instead.',
|
'Video.Unsupported.Mobile': 'Unfortunately, this video can\'t be played on Telegram Web. Try opening it with our **mobile app** instead.',
|
||||||
SlowModeWait: 'Slow Mode — %d',
|
SlowModeWait: 'Slow Mode — %d',
|
||||||
OpenMapWith: 'Open map with...',
|
OpenMapWith: 'Open map with...',
|
||||||
|
FullDateTimeFormat: '%@, %@',
|
||||||
} as ApiLangPack;
|
} as ApiLangPack;
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user