Localization: Fix translations sometimes not applied
This commit is contained in:
parent
9ebd0c4e00
commit
6bfcbe4da1
@ -27,7 +27,7 @@ import useMediaWithDownloadProgress from '../../hooks/useMediaWithDownloadProgre
|
||||
import useShowTransition from '../../hooks/useShowTransition';
|
||||
import useBuffering from '../../hooks/useBuffering';
|
||||
import useAudioPlayer from '../../hooks/useAudioPlayer';
|
||||
import useLang from '../../hooks/useLang';
|
||||
import useLang, { LangFn } from '../../hooks/useLang';
|
||||
|
||||
import Button from '../ui/Button';
|
||||
import ProgressSpinner from '../ui/ProgressSpinner';
|
||||
@ -177,7 +177,7 @@ const Audio: FC<OwnProps & StateProps> = ({
|
||||
onDateClick!(message.id, message.chatId);
|
||||
}, [onDateClick, message.id, message.chatId]);
|
||||
|
||||
useLang();
|
||||
const lang = useLang();
|
||||
|
||||
function getFirstLine() {
|
||||
if (isVoice) {
|
||||
@ -245,7 +245,7 @@ const Audio: FC<OwnProps & StateProps> = ({
|
||||
className="date"
|
||||
onClick={handleDateClick}
|
||||
>
|
||||
{formatPastTimeShort(date * 1000)}
|
||||
{formatPastTimeShort(lang, date * 1000)}
|
||||
</Link>
|
||||
)}
|
||||
</div>
|
||||
@ -293,7 +293,7 @@ const Audio: FC<OwnProps & StateProps> = ({
|
||||
)}
|
||||
{renderingFor === 'searchResult' && renderSearchResult()}
|
||||
{renderingFor !== 'searchResult' && audio && renderAudio(
|
||||
audio, isPlaying, playProgress, bufferedProgress, seekHandlers, date,
|
||||
lang, audio, isPlaying, playProgress, bufferedProgress, seekHandlers, date,
|
||||
onDateClick ? handleDateClick : undefined,
|
||||
)}
|
||||
{renderingFor !== 'searchResult' && voice && renderVoice(voice, renderedWaveform, isMediaUnread)}
|
||||
@ -302,6 +302,7 @@ const Audio: FC<OwnProps & StateProps> = ({
|
||||
};
|
||||
|
||||
function renderAudio(
|
||||
lang: LangFn,
|
||||
audio: ApiAudio,
|
||||
isPlaying: boolean,
|
||||
playProgress: number,
|
||||
@ -327,7 +328,7 @@ function renderAudio(
|
||||
{' '}
|
||||
•
|
||||
{' '}
|
||||
<Link className="date" onClick={handleDateClick}>{formatMediaDateTime(date * 1000)}</Link>
|
||||
<Link className="date" onClick={handleDateClick}>{formatMediaDateTime(lang, date * 1000)}</Link>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
|
||||
@ -54,7 +54,7 @@ const Avatar: FC<OwnProps> = ({
|
||||
const dataUri = useMedia(imageHash, false, ApiMediaFormat.DataUri, lastSyncTime);
|
||||
const { shouldRenderFullMedia, transitionClassNames } = useTransitionForMedia(dataUri, 'slow');
|
||||
|
||||
useLang();
|
||||
const lang = useLang();
|
||||
|
||||
let content: string | undefined = '';
|
||||
|
||||
@ -68,7 +68,7 @@ const Avatar: FC<OwnProps> = ({
|
||||
const userFullName = getUserFullName(user);
|
||||
content = userFullName ? getFirstLetters(userFullName, 2) : undefined;
|
||||
} else if (chat) {
|
||||
const title = getChatTitle(chat);
|
||||
const title = getChatTitle(lang, chat);
|
||||
content = title && getFirstLetters(title, isChatPrivate(chat.id) ? 2 : 1);
|
||||
} else if (text) {
|
||||
content = getFirstLetters(text, 2);
|
||||
|
||||
@ -7,6 +7,7 @@ import {
|
||||
formatMonthAndYear, formatHumanDate, formatTime,
|
||||
} from '../../util/dateFormat';
|
||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
||||
import useLang, { LangFn } from '../../hooks/useLang';
|
||||
|
||||
import Modal from '../ui/Modal';
|
||||
import Button from '../ui/Button';
|
||||
@ -42,6 +43,7 @@ const CalendarModal: FC<OwnProps> = ({
|
||||
onSubmit,
|
||||
onSecondButtonClick,
|
||||
}) => {
|
||||
const lang = useLang();
|
||||
const now = new Date();
|
||||
const defaultSelectedDate = useMemo(() => (selectedAt ? new Date(selectedAt) : new Date()), [selectedAt]);
|
||||
const maxDate = maxAt ? new Date(maxAt) : undefined;
|
||||
@ -181,7 +183,7 @@ const CalendarModal: FC<OwnProps> = ({
|
||||
</Button>
|
||||
|
||||
<h4>
|
||||
{formatMonthAndYear(selectedDate, IS_MOBILE_SCREEN)}
|
||||
{formatMonthAndYear(lang, selectedDate, IS_MOBILE_SCREEN)}
|
||||
</h4>
|
||||
|
||||
<Button
|
||||
@ -240,7 +242,7 @@ const CalendarModal: FC<OwnProps> = ({
|
||||
|
||||
<div className="footer">
|
||||
<Button onClick={handleSubmit}>
|
||||
{withTimePicker ? formatSubmitLabel(selectedDate) : submitButtonLabel}
|
||||
{withTimePicker ? formatSubmitLabel(lang, selectedDate) : submitButtonLabel}
|
||||
</Button>
|
||||
{secondButtonLabel && (
|
||||
<Button onClick={onSecondButtonClick} isText>
|
||||
@ -293,10 +295,14 @@ function formatInputTime(value: string | number) {
|
||||
return String(value).padStart(2, '0');
|
||||
}
|
||||
|
||||
function formatSubmitLabel(date: Date) {
|
||||
const day = formatHumanDate(date, true);
|
||||
function formatSubmitLabel(lang: LangFn, date: Date) {
|
||||
const day = formatHumanDate(lang, date, true);
|
||||
|
||||
return `Send ${day === 'Today' ? day : `on ${day}`} at ${formatTime(date)}`;
|
||||
if (day === 'Today') {
|
||||
return lang('Conversation.ScheduleMessage.SendToday', formatTime(date));
|
||||
}
|
||||
|
||||
return lang('Conversation.ScheduleMessage.SendOn', day).replace('%@', formatTime(date));
|
||||
}
|
||||
|
||||
export default memo(CalendarModal);
|
||||
|
||||
@ -37,7 +37,6 @@ type StateProps = {
|
||||
isBasicGroup: boolean;
|
||||
isSuperGroup: boolean;
|
||||
canDeleteForAll?: boolean;
|
||||
chatTitle: string;
|
||||
contactName?: string;
|
||||
};
|
||||
|
||||
@ -52,13 +51,15 @@ const DeleteChatModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
isBasicGroup,
|
||||
isSuperGroup,
|
||||
canDeleteForAll,
|
||||
chatTitle,
|
||||
contactName,
|
||||
onClose,
|
||||
leaveChannel,
|
||||
deleteHistory,
|
||||
deleteChannel,
|
||||
}) => {
|
||||
const lang = useLang();
|
||||
const chatTitle = getChatTitle(lang, chat);
|
||||
|
||||
const handleDeleteMessageForAll = useCallback(() => {
|
||||
deleteHistory({ chatId: chat.id, maxId: chat.lastMessage!.id, shouldDeleteForAll: true });
|
||||
onClose();
|
||||
@ -87,8 +88,6 @@ const DeleteChatModal: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
deleteChannel,
|
||||
]);
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
function renderHeader() {
|
||||
return (
|
||||
<div className="modal-header">
|
||||
@ -182,7 +181,6 @@ export default memo(withGlobal<OwnProps>(
|
||||
isBasicGroup: isChatBasicGroup(chat),
|
||||
isSuperGroup: isChatSuperGroup(chat),
|
||||
canDeleteForAll,
|
||||
chatTitle: getChatTitle(chat),
|
||||
contactName,
|
||||
};
|
||||
},
|
||||
|
||||
@ -51,7 +51,7 @@ const EmbeddedMessage: FC<OwnProps> = ({
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
const senderTitle = sender && getSenderTitle(sender);
|
||||
const senderTitle = sender && getSenderTitle(lang, sender);
|
||||
|
||||
return (
|
||||
<div
|
||||
|
||||
@ -8,6 +8,7 @@ import { formatMediaDateTime, formatPastTimeShort } from '../../util/dateFormat'
|
||||
import { getColorFromExtension, getFileSizeString } from './helpers/documentInfo';
|
||||
import { getDocumentThumbnailDimensions } from './helpers/mediaDimensions';
|
||||
import renderText from './helpers/renderText';
|
||||
import useLang from '../../hooks/useLang';
|
||||
|
||||
import ProgressSpinner from '../ui/ProgressSpinner';
|
||||
import Link from '../ui/Link';
|
||||
@ -53,6 +54,7 @@ const File: FC<OwnProps> = ({
|
||||
onClick,
|
||||
onDateClick,
|
||||
}) => {
|
||||
const lang = useLang();
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
let elementRef = useRef<HTMLDivElement>(null);
|
||||
if (ref) {
|
||||
@ -136,13 +138,13 @@ const File: FC<OwnProps> = ({
|
||||
{!sender && timestamp && (
|
||||
<>
|
||||
{' '}
|
||||
<Link onClick={onDateClick}>{formatMediaDateTime(timestamp * 1000)}</Link>
|
||||
<Link onClick={onDateClick}>{formatMediaDateTime(lang, timestamp * 1000)}</Link>
|
||||
</>
|
||||
)}
|
||||
</div>
|
||||
</div>
|
||||
{sender && timestamp && (
|
||||
<Link onClick={onDateClick}>{formatPastTimeShort(timestamp * 1000)}</Link>
|
||||
<Link onClick={onDateClick}>{formatPastTimeShort(lang, timestamp * 1000)}</Link>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
|
||||
@ -103,7 +103,7 @@ const GroupChatInfo: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
}
|
||||
|
||||
const handle = withUsername ? chat.username : undefined;
|
||||
const groupStatus = getGroupStatus(chat, lang);
|
||||
const groupStatus = getGroupStatus(lang, chat);
|
||||
const onlineStatus = onlineCount ? `, ${lang('OnlineCount', onlineCount, 'i')}` : undefined;
|
||||
|
||||
return (
|
||||
@ -125,7 +125,7 @@ const GroupChatInfo: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
/>
|
||||
<div className="info">
|
||||
<div className="title">
|
||||
<h3>{renderText(getChatTitle(chat))}</h3>
|
||||
<h3>{renderText(getChatTitle(lang, chat))}</h3>
|
||||
{chat.isVerified && <VerifiedIcon />}
|
||||
</div>
|
||||
{renderStatusOrTyping()}
|
||||
@ -134,7 +134,7 @@ const GroupChatInfo: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
);
|
||||
};
|
||||
|
||||
function getGroupStatus(chat: ApiChat, lang: LangFn) {
|
||||
function getGroupStatus(lang: LangFn, chat: ApiChat) {
|
||||
const chatTypeString = lang(getChatTypeString(chat));
|
||||
const { membersCount } = chat;
|
||||
|
||||
|
||||
@ -1,8 +1,12 @@
|
||||
import React, { FC, memo } from '../../lib/teact/teact';
|
||||
|
||||
import { ApiMessage, ApiMessageOutgoingStatus } from '../../api/types';
|
||||
|
||||
import { formatPastTimeShort } from '../../util/dateFormat';
|
||||
import useLang from '../../hooks/useLang';
|
||||
|
||||
import MessageOutgoingStatus from './MessageOutgoingStatus';
|
||||
|
||||
import './LastMessageMeta.scss';
|
||||
|
||||
type OwnProps = {
|
||||
@ -11,12 +15,13 @@ type OwnProps = {
|
||||
};
|
||||
|
||||
const LastMessageMeta: FC<OwnProps> = ({ message, outgoingStatus }) => {
|
||||
const lang = useLang();
|
||||
return (
|
||||
<div className="LastMessageMeta">
|
||||
{outgoingStatus && (
|
||||
<MessageOutgoingStatus status={outgoingStatus} />
|
||||
)}
|
||||
<span className="time">{formatPastTimeShort(message.date * 1000)}</span>
|
||||
<span className="time">{formatPastTimeShort(lang, message.date * 1000)}</span>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
@ -40,7 +40,7 @@ const PickerSelectedItem: FC<OwnProps & StateProps> = ({
|
||||
user,
|
||||
className,
|
||||
}) => {
|
||||
useLang();
|
||||
const lang = useLang();
|
||||
|
||||
let iconElement: any;
|
||||
let titleText: any;
|
||||
@ -65,7 +65,7 @@ const PickerSelectedItem: FC<OwnProps & StateProps> = ({
|
||||
|
||||
const name = !chat || (user && !user.isSelf)
|
||||
? getUserFirstOrLastName(user)
|
||||
: getChatTitle(chat, user);
|
||||
: getChatTitle(lang, chat, user);
|
||||
|
||||
titleText = name ? renderText(name) : undefined;
|
||||
}
|
||||
|
||||
@ -104,7 +104,7 @@ const PrivateChatInfo: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
return (
|
||||
<div className={`status ${isUserOnline(user) ? 'online' : ''}`}>
|
||||
{withUsername && user.username && <span className="handle">{user.username}</span>}
|
||||
<span className="user-status">{getUserStatus(user, lang)}</span>
|
||||
<span className="user-status">{getUserStatus(lang, user)}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -94,7 +94,7 @@ const WebLink: FC<OwnProps> = ({ message, senderTitle, onMessageClick }) => {
|
||||
className="date"
|
||||
onClick={handleMessageClick}
|
||||
>
|
||||
{formatPastTimeShort(message.date * 1000)}
|
||||
{formatPastTimeShort(lang, message.date * 1000)}
|
||||
</Link>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@ -46,7 +46,7 @@ export function renderActionMessageText(
|
||||
text,
|
||||
'%action_origin%',
|
||||
actionOrigin
|
||||
? (!options.isEmbedded && renderOriginContent(actionOrigin, options.asPlain)) || NBSP
|
||||
? (!options.isEmbedded && renderOriginContent(lang, actionOrigin, options.asPlain)) || NBSP
|
||||
: 'User',
|
||||
);
|
||||
|
||||
@ -144,9 +144,9 @@ function renderMessageContent(lang: LangFn, message: ApiMessage, options: Action
|
||||
);
|
||||
}
|
||||
|
||||
function renderOriginContent(origin: ApiUser | ApiChat, asPlain?: boolean) {
|
||||
function renderOriginContent(lang: LangFn, origin: ApiUser | ApiChat, asPlain?: boolean) {
|
||||
return isChat(origin)
|
||||
? renderChatContent(origin, asPlain)
|
||||
? renderChatContent(lang, origin, asPlain)
|
||||
: renderUserContent(origin, asPlain);
|
||||
}
|
||||
|
||||
@ -160,8 +160,8 @@ function renderUserContent(sender: ApiUser, asPlain?: boolean): string | TextPar
|
||||
return <UserLink className="action-link" sender={sender}>{sender && renderText(text!)}</UserLink>;
|
||||
}
|
||||
|
||||
function renderChatContent(chat: ApiChat, asPlain?: boolean): string | TextPart | undefined {
|
||||
const text = trimText(getChatTitle(chat));
|
||||
function renderChatContent(lang: LangFn, chat: ApiChat, asPlain?: boolean): string | TextPart | undefined {
|
||||
const text = trimText(getChatTitle(lang, chat));
|
||||
|
||||
if (asPlain) {
|
||||
return text;
|
||||
|
||||
@ -221,7 +221,7 @@ const Chat: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
);
|
||||
}
|
||||
|
||||
const senderName = getMessageSenderName(chatId, lastMessageSender);
|
||||
const senderName = getMessageSenderName(lang, chatId, lastMessageSender);
|
||||
|
||||
return (
|
||||
<p className="last-message">
|
||||
@ -257,7 +257,7 @@ const Chat: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
/>
|
||||
<div className="info">
|
||||
<div className="title">
|
||||
<h3>{renderText(getChatTitle(chat, privateChatUser))}</h3>
|
||||
<h3>{renderText(getChatTitle(lang, chat, privateChatUser))}</h3>
|
||||
{chat.isVerified && <VerifiedIcon />}
|
||||
{isMuted && <i className="icon-muted-chat" />}
|
||||
{chat.lastMessage && (
|
||||
|
||||
@ -88,13 +88,13 @@ const AudioResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
key={message.id}
|
||||
>
|
||||
{shouldDrawDateDivider && (
|
||||
<p className="section-heading">{formatMonthAndYear(new Date(message.date * 1000))}</p>
|
||||
<p className="section-heading">{formatMonthAndYear(lang, new Date(message.date * 1000))}</p>
|
||||
)}
|
||||
<Audio
|
||||
key={message.id}
|
||||
message={message}
|
||||
renderingFor="searchResult"
|
||||
senderTitle={getSenderName(message, chatsById, usersById)}
|
||||
senderTitle={getSenderName(lang, message, chatsById, usersById)}
|
||||
date={message.date}
|
||||
lastSyncTime={lastSyncTime}
|
||||
className="scroll-item"
|
||||
|
||||
@ -84,12 +84,12 @@ const ChatMessage: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
<div className="info">
|
||||
<div className="info-row">
|
||||
<div className="title">
|
||||
<h3>{renderText(getChatTitle(chat, privateChatUser))}</h3>
|
||||
<h3>{renderText(getChatTitle(lang, chat, privateChatUser))}</h3>
|
||||
{chat.isVerified && <VerifiedIcon />}
|
||||
</div>
|
||||
<div className="message-date">
|
||||
<Link className="date">
|
||||
{formatPastTimeShort(message.date * 1000)}
|
||||
{formatPastTimeShort(lang, message.date * 1000)}
|
||||
</Link>
|
||||
</div>
|
||||
|
||||
|
||||
@ -23,7 +23,6 @@ import DateSuggest from './DateSuggest';
|
||||
import Link from '../../ui/Link';
|
||||
import NothingFound from '../../common/NothingFound';
|
||||
import PickerSelectedItem from '../../common/PickerSelectedItem';
|
||||
import { getTranslation } from '../../../util/langProvider';
|
||||
|
||||
export type OwnProps = {
|
||||
searchQuery?: string;
|
||||
@ -63,6 +62,8 @@ const ChatResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
foundIds, globalMessagesByChatId, chatsById, usersById, fetchingStatus, lastSyncTime,
|
||||
onReset, onSearchDateSelect, openChat, addRecentlyFoundChatId, searchMessagesGlobal, setGlobalSearchChatId,
|
||||
}) => {
|
||||
const lang = useLang();
|
||||
|
||||
const [shouldShowMoreLocal, setShouldShowMoreLocal] = useState<boolean>(false);
|
||||
const [shouldShowMoreGlobal, setShouldShowMoreGlobal] = useState<boolean>(false);
|
||||
|
||||
@ -114,14 +115,14 @@ const ChatResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
: [];
|
||||
|
||||
return [
|
||||
...(currentUserId && searchWords(getTranslation('SavedMessages'), searchQuery) ? [currentUserId] : []),
|
||||
...(currentUserId && searchWords(lang('SavedMessages'), searchQuery) ? [currentUserId] : []),
|
||||
...sortChatIds(unique([
|
||||
...foundContactIds,
|
||||
...(localChatIds || []),
|
||||
...(localUserIds || []),
|
||||
]), chatsById),
|
||||
];
|
||||
}, [searchQuery, localContactIds, currentUserId, localChatIds, localUserIds, chatsById, usersById]);
|
||||
}, [searchQuery, localContactIds, currentUserId, lang, localChatIds, localUserIds, chatsById, usersById]);
|
||||
|
||||
const globalResults = useMemo(() => {
|
||||
if (!searchQuery || searchQuery.length < MIN_QUERY_LENGTH_FOR_GLOBAL_SEARCH || !globalChatIds || !globalUserIds) {
|
||||
@ -156,8 +157,6 @@ const ChatResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
setShouldShowMoreGlobal(!shouldShowMoreGlobal);
|
||||
}, [shouldShowMoreGlobal]);
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
function renderFoundMessage(message: ApiMessage) {
|
||||
const text = getMessageSummaryText(lang, message);
|
||||
const chat = chatsById[message.chatId];
|
||||
|
||||
@ -84,14 +84,14 @@ const FileResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
key={message.id}
|
||||
>
|
||||
{shouldDrawDateDivider && (
|
||||
<p className="section-heading">{formatMonthAndYear(new Date(message.date * 1000))}</p>
|
||||
<p className="section-heading">{formatMonthAndYear(lang, new Date(message.date * 1000))}</p>
|
||||
)}
|
||||
<Document
|
||||
message={message}
|
||||
withDate
|
||||
datetime={message.date}
|
||||
smaller
|
||||
sender={getSenderName(message, chatsById, usersById)}
|
||||
sender={getSenderName(lang, message, chatsById, usersById)}
|
||||
className="scroll-item"
|
||||
onDateClick={handleMessageFocus}
|
||||
/>
|
||||
|
||||
@ -81,12 +81,12 @@ const LinkResults: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
key={message.id}
|
||||
>
|
||||
{shouldDrawDateDivider && (
|
||||
<p className="section-heading">{formatMonthAndYear(new Date(message.date * 1000))}</p>
|
||||
<p className="section-heading">{formatMonthAndYear(lang, new Date(message.date * 1000))}</p>
|
||||
)}
|
||||
<WebLink
|
||||
key={message.id}
|
||||
message={message}
|
||||
senderTitle={getSenderName(message, chatsById, usersById)}
|
||||
senderTitle={getSenderName(lang, message, chatsById, usersById)}
|
||||
onMessageClick={handleMessageFocus}
|
||||
/>
|
||||
</div>
|
||||
|
||||
@ -5,9 +5,10 @@ import {
|
||||
isChatPrivate,
|
||||
isChatGroup,
|
||||
} from '../../../../modules/helpers';
|
||||
import { LangFn } from '../../../../hooks/useLang';
|
||||
|
||||
export function getSenderName(
|
||||
message: ApiMessage, chatsById: Record<number, ApiChat>, usersById: Record<number, ApiUser>,
|
||||
lang: LangFn, message: ApiMessage, chatsById: Record<number, ApiChat>, usersById: Record<number, ApiUser>,
|
||||
) {
|
||||
const { senderId } = message;
|
||||
if (!senderId) {
|
||||
@ -16,14 +17,14 @@ export function getSenderName(
|
||||
|
||||
const sender = isChatPrivate(senderId) ? usersById[senderId] : chatsById[senderId];
|
||||
|
||||
let senderName = getSenderTitle(sender);
|
||||
let senderName = getSenderTitle(lang, sender);
|
||||
|
||||
const chat = chatsById[message.chatId];
|
||||
if (chat) {
|
||||
if (isChatPrivate(senderId) && (sender as ApiUser).isSelf) {
|
||||
senderName = `You → ${getChatTitle(chat)}`;
|
||||
senderName = `${lang('FromYou')} → ${getChatTitle(lang, chat)}`;
|
||||
} else if (isChatGroup(chat)) {
|
||||
senderName += ` → ${getChatTitle(chat)}`;
|
||||
senderName += ` → ${getChatTitle(lang, chat)}`;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -103,7 +103,7 @@ const SettingsPrivacyActiveSessions: FC<StateProps & DispatchProps> = ({
|
||||
}]}
|
||||
>
|
||||
<div className="multiline-menu-item full-size">
|
||||
<span className="date">{formatPastTimeShort(session.dateActive * 1000)}</span>
|
||||
<span className="date">{formatPastTimeShort(lang, session.dateActive * 1000)}</span>
|
||||
<span className="title">{session.appName}</span>
|
||||
<span className="subtitle black tight">{getDeviceEnvironment(session)}</span>
|
||||
<span className="subtitle">{session.ip} - {getLocation(session)}</span>
|
||||
|
||||
@ -68,7 +68,7 @@ const SettingsPrivacyBlockedUsers: FC<StateProps & DispatchProps> = ({
|
||||
>
|
||||
<Avatar size="medium" user={user} chat={chat} />
|
||||
<div className="contact-info">
|
||||
<h3>{renderText((isPrivate ? getUserFullName(user) : getChatTitle(chat!)) || '')}</h3>
|
||||
<h3>{renderText((isPrivate ? getUserFullName(user) : getChatTitle(lang, chat!)) || '')}</h3>
|
||||
{user && user.phoneNumber && (
|
||||
<div className="contact-phone">{formatPhoneNumberWithCode(user.phoneNumber)}</div>
|
||||
)}
|
||||
|
||||
@ -49,6 +49,8 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps & Dispatc
|
||||
setPrivacySettings,
|
||||
onScreenSelect,
|
||||
}) => {
|
||||
const lang = useLang();
|
||||
|
||||
const selectedContactIds = useMemo(() => {
|
||||
if (!settings) {
|
||||
return [];
|
||||
@ -98,12 +100,12 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps & Dispatc
|
||||
((isChatPrivate(chat.id) && chat.id !== currentUserId) || isChatGroup(chat))
|
||||
&& (
|
||||
!searchQuery
|
||||
|| searchWords(getChatTitle(chat), searchQuery)
|
||||
|| searchWords(getChatTitle(lang, chat), searchQuery)
|
||||
|| selectedContactIds.includes(chat.id)
|
||||
)
|
||||
))
|
||||
.map(({ id }) => id);
|
||||
}, [chats, currentUserId, searchQuery, selectedContactIds]);
|
||||
}, [chats, currentUserId, lang, searchQuery, selectedContactIds]);
|
||||
|
||||
const handleSelectedContactIdsChange = useCallback((value: number[]) => {
|
||||
setNewSelectedContactIds(value);
|
||||
@ -120,8 +122,6 @@ const SettingsPrivacyVisibilityExceptionList: FC<OwnProps & StateProps & Dispatc
|
||||
onScreenSelect(SettingsScreens.Privacy);
|
||||
}, [isAllowList, newSelectedContactIds, onScreenSelect, screen, setPrivacySettings]);
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
return (
|
||||
<div className="NewChat-inner step-1">
|
||||
<Picker
|
||||
|
||||
@ -6,6 +6,7 @@ import { withGlobal } from '../../../../lib/teact/teactn';
|
||||
import { GlobalActions } from '../../../../global/types';
|
||||
import { ApiChat } from '../../../../api/types';
|
||||
|
||||
import useLang from '../../../../hooks/useLang';
|
||||
import { pick } from '../../../../util/iteratees';
|
||||
import searchWords from '../../../../util/searchWords';
|
||||
import { prepareChatList, getChatTitle } from '../../../../modules/helpers';
|
||||
@ -49,6 +50,7 @@ const SettingsFoldersChatFilters: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
const { chatFilter } = state;
|
||||
const { selectedChatIds, selectedChatTypes } = selectChatFilters(state, mode, true);
|
||||
|
||||
const lang = useLang();
|
||||
const chats = useMemo(() => {
|
||||
const activeChatArrays = listIds
|
||||
? prepareChatList(chatsById, listIds, orderedPinnedIds, 'all')
|
||||
@ -78,11 +80,11 @@ const SettingsFoldersChatFilters: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
return chats
|
||||
.filter((chat) => (
|
||||
!chatFilter
|
||||
|| searchWords(getChatTitle(chat), chatFilter)
|
||||
|| searchWords(getChatTitle(lang, chat), chatFilter)
|
||||
|| selectedChatIds.includes(chat.id)
|
||||
))
|
||||
.map(({ id }) => id);
|
||||
}, [chats, chatFilter, selectedChatIds]);
|
||||
}, [chats, chatFilter, lang, selectedChatIds]);
|
||||
|
||||
const handleFilterChange = useCallback((newFilter: string) => {
|
||||
dispatch({
|
||||
|
||||
@ -103,7 +103,7 @@ const SettingsFoldersMain: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
id: folder.id,
|
||||
title: folder.title,
|
||||
subtitle: getFolderDescriptionText(
|
||||
chatsById, usersById, folder, chatIds, lang, notifySettings, notifyExceptions,
|
||||
lang, chatsById, usersById, folder, chatIds, notifySettings, notifyExceptions,
|
||||
),
|
||||
};
|
||||
});
|
||||
|
||||
@ -58,6 +58,8 @@ const ForwardPicker: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
// eslint-disable-next-line no-null/no-null
|
||||
const inputRef = useRef<HTMLInputElement>(null);
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
useEffect(() => {
|
||||
if (isOpen) {
|
||||
if (!IS_MOBILE_SCREEN) {
|
||||
@ -101,10 +103,10 @@ const ForwardPicker: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
return true;
|
||||
}
|
||||
|
||||
return searchWords(getChatTitle(chatsById[id], undefined, id === currentUserId), filter);
|
||||
return searchWords(getChatTitle(lang, chatsById[id], undefined, id === currentUserId), filter);
|
||||
}),
|
||||
], chatsById, undefined, currentUserId ? [currentUserId] : undefined);
|
||||
}, [activeListIds, archivedListIds, chatsById, currentUserId, filter]);
|
||||
}, [activeListIds, archivedListIds, chatsById, currentUserId, filter, lang]);
|
||||
|
||||
const [viewportIds, getMore] = useInfiniteScroll(loadMoreChats, chatIds, Boolean(filter));
|
||||
|
||||
@ -112,8 +114,6 @@ const ForwardPicker: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
setFilter(e.currentTarget.value);
|
||||
}, []);
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
const modalHeader = (
|
||||
<div className="modal-header">
|
||||
<Button
|
||||
|
||||
@ -48,7 +48,7 @@ const SenderInfo: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
}
|
||||
|
||||
const isFromChat = sender.id < 0;
|
||||
const senderTitle = getSenderTitle(sender);
|
||||
const senderTitle = getSenderTitle(lang, sender);
|
||||
|
||||
return (
|
||||
<div className="SenderInfo" onClick={handleFocusMessage}>
|
||||
@ -62,7 +62,7 @@ const SenderInfo: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
{senderTitle && renderText(senderTitle)}
|
||||
</div>
|
||||
<div className="date">
|
||||
{isAvatar ? lang('lng_mediaview_profile_photo') : formatMediaDateTime(message!.date * 1000)}
|
||||
{isAvatar ? lang('lng_mediaview_profile_photo') : formatMediaDateTime(lang, message!.date * 1000)}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -2,7 +2,9 @@ import React, { FC, useCallback } from '../../lib/teact/teact';
|
||||
import { withGlobal } from '../../lib/teact/teactn';
|
||||
|
||||
import { GlobalActions } from '../../global/types';
|
||||
import { ApiAudio, ApiMessage } from '../../api/types';
|
||||
import {
|
||||
ApiAudio, ApiChat, ApiMessage, ApiUser,
|
||||
} from '../../api/types';
|
||||
|
||||
import { IS_MOBILE_SCREEN } from '../../util/environment';
|
||||
import * as mediaLoader from '../../util/mediaLoader';
|
||||
@ -28,14 +30,17 @@ type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
senderName?: string;
|
||||
sender?: ApiChat | ApiUser;
|
||||
};
|
||||
|
||||
type DispatchProps = Pick<GlobalActions, 'focusMessage' | 'closeAudioPlayer'>;
|
||||
|
||||
const AudioPlayer: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
message, className, noUi, senderName, focusMessage, closeAudioPlayer,
|
||||
message, className, noUi, sender, focusMessage, closeAudioPlayer,
|
||||
}) => {
|
||||
const lang = useLang();
|
||||
|
||||
const senderName = sender ? getSenderTitle(lang, sender) : undefined;
|
||||
const mediaData = mediaLoader.getFromMemory(getMessageMediaHash(message, 'inline')!) as (string | undefined);
|
||||
const { playPause, isPlaying } = useAudioPlayer(
|
||||
getMessageKey(message), getMediaDuration(message)!, mediaData, undefined, undefined, true,
|
||||
@ -52,8 +57,6 @@ const AudioPlayer: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
closeAudioPlayer();
|
||||
}, [closeAudioPlayer, isPlaying, playPause]);
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
if (noUi) {
|
||||
return undefined;
|
||||
}
|
||||
@ -117,11 +120,10 @@ function renderVoice(subtitle: string, senderName?: string) {
|
||||
}
|
||||
|
||||
export default withGlobal<OwnProps>(
|
||||
(global, { message }) => {
|
||||
(global, { message }): StateProps => {
|
||||
const sender = selectSender(global, message);
|
||||
const senderName = sender ? getSenderTitle(sender) : undefined;
|
||||
|
||||
return { senderName };
|
||||
return { sender };
|
||||
},
|
||||
(setGlobal, actions): DispatchProps => pick(actions, ['focusMessage', 'closeAudioPlayer']),
|
||||
)(AudioPlayer);
|
||||
|
||||
@ -707,9 +707,9 @@ function renderMessages(
|
||||
lang('MessageScheduledUntilOnline')
|
||||
)}
|
||||
{isSchedule && dateGroup.originalDate !== SCHEDULED_WHEN_ONLINE && (
|
||||
lang('MessageScheduledOn', formatHumanDate(dateGroup.datetime, undefined, true))
|
||||
lang('MessageScheduledOn', formatHumanDate(lang, dateGroup.datetime, undefined, true))
|
||||
)}
|
||||
{!isSchedule && formatHumanDate(dateGroup.datetime)}
|
||||
{!isSchedule && formatHumanDate(lang, dateGroup.datetime)}
|
||||
</span>
|
||||
</div>
|
||||
{flatten(senderGroups)}
|
||||
|
||||
@ -9,7 +9,7 @@ import {
|
||||
ApiMessage,
|
||||
ApiChat,
|
||||
ApiTypingStatus,
|
||||
MAIN_THREAD_ID,
|
||||
MAIN_THREAD_ID, ApiUser,
|
||||
} from '../../api/types';
|
||||
|
||||
import {
|
||||
@ -72,16 +72,16 @@ type OwnProps = {
|
||||
};
|
||||
|
||||
type StateProps = {
|
||||
chat?: ApiChat;
|
||||
pinnedMessageIds?: number[] | number;
|
||||
messagesById?: Record<number, ApiMessage>;
|
||||
canUnpin?: boolean;
|
||||
topMessageTitle?: string;
|
||||
topMessageSender?: ApiChat | ApiUser;
|
||||
typingStatus?: ApiTypingStatus;
|
||||
isSelectModeActive?: boolean;
|
||||
isLeftColumnShown?: boolean;
|
||||
isRightColumnShown?: boolean;
|
||||
audioMessage?: ApiMessage;
|
||||
chatTitleLength?: number;
|
||||
chatsById?: Record<number, ApiChat>;
|
||||
originChatId: number;
|
||||
messagesCount?: number;
|
||||
@ -102,13 +102,13 @@ const MiddleHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
pinnedMessageIds,
|
||||
messagesById,
|
||||
canUnpin,
|
||||
topMessageTitle,
|
||||
topMessageSender,
|
||||
typingStatus,
|
||||
isSelectModeActive,
|
||||
isLeftColumnShown,
|
||||
isRightColumnShown,
|
||||
audioMessage,
|
||||
chatTitleLength,
|
||||
chat,
|
||||
chatsById,
|
||||
originChatId,
|
||||
messagesCount,
|
||||
@ -123,10 +123,14 @@ const MiddleHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
toggleLeftColumn,
|
||||
exitMessageSelectMode,
|
||||
}) => {
|
||||
const lang = useLang();
|
||||
|
||||
const [pinnedMessageIndex, setPinnedMessageIndex] = useState(0);
|
||||
const pinnedMessageId = Array.isArray(pinnedMessageIds) ? pinnedMessageIds[pinnedMessageIndex] : pinnedMessageIds;
|
||||
const pinnedMessage = messagesById && pinnedMessageId ? messagesById[pinnedMessageId] : undefined;
|
||||
const pinnedMessagesCount = Array.isArray(pinnedMessageIds) ? pinnedMessageIds.length : (pinnedMessageIds ? 1 : 0);
|
||||
const chatTitleLength = chat && getChatTitle(lang, chat).length;
|
||||
const topMessageTitle = topMessageSender ? getSenderTitle(lang, topMessageSender) : undefined;
|
||||
|
||||
useEffect(() => {
|
||||
if (threadId === MAIN_THREAD_ID && lastSyncTime) {
|
||||
@ -201,13 +205,13 @@ const MiddleHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
|
||||
let isActive = false;
|
||||
|
||||
const totalCount = Object.values(chatsById).reduce((total, chat) => {
|
||||
if (isChatArchived(chat)) {
|
||||
const totalCount = Object.values(chatsById).reduce((total, currentChat) => {
|
||||
if (isChatArchived(currentChat)) {
|
||||
return total;
|
||||
}
|
||||
|
||||
const count = chat.unreadCount || 0;
|
||||
if (count && (!chat.isMuted || chat.unreadMentionsCount)) {
|
||||
const count = currentChat.unreadCount || 0;
|
||||
if (count && (!currentChat.isMuted || currentChat.unreadMentionsCount)) {
|
||||
isActive = true;
|
||||
}
|
||||
|
||||
@ -284,8 +288,6 @@ const MiddleHeader: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
}
|
||||
}, [shouldUseStackedToolsClass, canRevealTools, canToolsCollideWithChatInfo, isRightColumnShown]);
|
||||
|
||||
const lang = useLang();
|
||||
|
||||
function renderInfo() {
|
||||
return (
|
||||
messageListType === 'thread' && threadId === MAIN_THREAD_ID ? (
|
||||
@ -435,7 +437,7 @@ export default memo(withGlobal<OwnProps>(
|
||||
isRightColumnShown: selectIsRightColumnShown(global),
|
||||
isSelectModeActive: selectIsInSelectMode(global),
|
||||
audioMessage,
|
||||
chatTitleLength: chat && getChatTitle(chat).length,
|
||||
chat,
|
||||
chatsById,
|
||||
originChatId: originChat ? originChat.id : chatId,
|
||||
messagesCount,
|
||||
@ -454,14 +456,13 @@ export default memo(withGlobal<OwnProps>(
|
||||
if (threadId !== MAIN_THREAD_ID) {
|
||||
const pinnedMessageId = selectThreadTopMessageId(global, chatId, threadId);
|
||||
const message = pinnedMessageId ? selectChatMessage(global, chatId, pinnedMessageId) : undefined;
|
||||
const sender = message ? selectForwardedSender(global, message) : undefined;
|
||||
const topMessageTitle = sender ? getSenderTitle(sender) : undefined;
|
||||
const topMessageSender = message ? selectForwardedSender(global, message) : undefined;
|
||||
|
||||
return {
|
||||
...state,
|
||||
pinnedMessageIds: pinnedMessageId,
|
||||
canUnpin: false,
|
||||
topMessageTitle,
|
||||
topMessageSender,
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@ -636,7 +636,7 @@ const Message: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
let senderTitle;
|
||||
let senderColor;
|
||||
if (senderPeer) {
|
||||
senderTitle = getSenderTitle(senderPeer);
|
||||
senderTitle = getSenderTitle(lang, senderPeer);
|
||||
|
||||
if (!asForwarded) {
|
||||
senderColor = `color-${getUserColorKey(senderPeer)}`;
|
||||
|
||||
@ -157,7 +157,7 @@ const PrivateChatInfo: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
if (user) {
|
||||
return (
|
||||
<div className={`status ${isUserOnline(user) ? 'online' : ''}`}>
|
||||
<span className="user-status">{getUserStatus(user, lang)}</span>
|
||||
<span className="user-status">{getUserStatus(lang, user)}</span>
|
||||
</div>
|
||||
);
|
||||
}
|
||||
|
||||
@ -13,6 +13,7 @@ import { getFirstLetters } from '../../util/textFormat';
|
||||
import useMedia from '../../hooks/useMedia';
|
||||
import useBlurSync from '../../hooks/useBlurSync';
|
||||
import usePrevious from '../../hooks/usePrevious';
|
||||
import useLang from '../../hooks/useLang';
|
||||
|
||||
import Spinner from '../ui/Spinner';
|
||||
|
||||
@ -37,6 +38,7 @@ const ProfilePhoto: FC<OwnProps> = ({
|
||||
lastSyncTime,
|
||||
onClick,
|
||||
}) => {
|
||||
const lang = useLang();
|
||||
const isDeleted = user && isDeletedUser(user);
|
||||
|
||||
function getMediaHash(size: 'normal' | 'big' = 'big', forceAvatar?: boolean) {
|
||||
@ -80,7 +82,7 @@ const ProfilePhoto: FC<OwnProps> = ({
|
||||
const userFullName = getUserFullName(user);
|
||||
content = userFullName ? getFirstLetters(userFullName, 2) : undefined;
|
||||
} else if (!imageSrc && chat) {
|
||||
const title = getChatTitle(chat);
|
||||
const title = getChatTitle(lang, chat);
|
||||
content = title && getFirstLetters(title, isChatPrivate(chat.id) ? 2 : 1);
|
||||
} else {
|
||||
content = (
|
||||
|
||||
@ -100,7 +100,7 @@ const RightSearch: FC<OwnProps & StateProps & DispatchProps> = ({
|
||||
const renderSearchResult = ({
|
||||
message, senderUser, senderChat, onClick,
|
||||
}: Result) => {
|
||||
const title = senderChat ? getChatTitle(senderChat) : getUserFullName(senderUser);
|
||||
const title = senderChat ? getChatTitle(lang, senderChat) : getUserFullName(senderUser);
|
||||
const text = getMessageSummaryText(lang, message);
|
||||
|
||||
return (
|
||||
|
||||
@ -11,7 +11,6 @@ import { NotifyException, NotifySettings } from '../../types';
|
||||
import { ARCHIVED_FOLDER_ID } from '../../config';
|
||||
import { orderBy } from '../../util/iteratees';
|
||||
import { getUserFirstOrLastName } from './users';
|
||||
import { getTranslation } from '../../util/langProvider';
|
||||
import { LangFn } from '../../hooks/useLang';
|
||||
|
||||
export function isChatPrivate(chatId: number) {
|
||||
@ -60,11 +59,11 @@ export function getPrivateChatUserId(chat: ApiChat) {
|
||||
}
|
||||
|
||||
// TODO Get rid of `user`
|
||||
export function getChatTitle(chat: ApiChat, user?: ApiUser, isSelf = false) {
|
||||
export function getChatTitle(lang: LangFn, chat: ApiChat, user?: ApiUser, isSelf = false) {
|
||||
if (isSelf || (user && chat.id === user.id && user.isSelf)) {
|
||||
return getTranslation('SavedMessages');
|
||||
return lang('SavedMessages');
|
||||
}
|
||||
return chat.title || getTranslation('HiddenName');
|
||||
return chat.title || lang('HiddenName');
|
||||
}
|
||||
|
||||
export function getChatDescription(chat: ApiChat) {
|
||||
@ -388,11 +387,11 @@ export function getFolderUnreadDialogs(
|
||||
}
|
||||
|
||||
export function getFolderDescriptionText(
|
||||
lang: LangFn,
|
||||
chatsById: Record<number, ApiChat>,
|
||||
usersById: Record<number, ApiUser>,
|
||||
folder: ApiChatFolder,
|
||||
chatIdsCache: number[],
|
||||
lang: LangFn,
|
||||
notifySettings: NotifySettings,
|
||||
notifyExceptions?: Record<number, NotifyException>,
|
||||
) {
|
||||
@ -453,13 +452,13 @@ export function isChat(chatOrUser?: ApiUser | ApiChat): chatOrUser is ApiChat {
|
||||
return chatOrUser.id < 0;
|
||||
}
|
||||
|
||||
export function getMessageSenderName(chatId: number, sender?: ApiUser) {
|
||||
export function getMessageSenderName(lang: LangFn, chatId: number, sender?: ApiUser) {
|
||||
if (!sender || isChatPrivate(chatId)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
if (sender.isSelf) {
|
||||
return getTranslation('FromYou');
|
||||
return lang('FromYou');
|
||||
}
|
||||
|
||||
return getUserFirstOrLastName(sender);
|
||||
|
||||
@ -197,8 +197,8 @@ export function isAnonymousOwnMessage(message: ApiMessage) {
|
||||
return Boolean(message.senderId) && message.senderId! < 0 && isOwnMessage(message);
|
||||
}
|
||||
|
||||
export function getSenderTitle(sender: ApiUser | ApiChat) {
|
||||
return sender.id > 0 ? getUserFullName(sender as ApiUser) : getChatTitle(sender as ApiChat);
|
||||
export function getSenderTitle(lang: LangFn, sender: ApiUser | ApiChat) {
|
||||
return sender.id > 0 ? getUserFullName(sender as ApiUser) : getChatTitle(lang, sender as ApiChat);
|
||||
}
|
||||
|
||||
export function getSendingState(message: ApiMessage) {
|
||||
|
||||
@ -64,7 +64,7 @@ export function getUserFullName(user?: ApiUser) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getUserStatus(user: ApiUser, lang: LangFn) {
|
||||
export function getUserStatus(lang: LangFn, user: ApiUser) {
|
||||
if (user.id === SERVICE_NOTIFICATIONS_USER_ID) {
|
||||
return lang('ServiceNotifications').toLowerCase();
|
||||
}
|
||||
@ -137,7 +137,7 @@ export function getUserStatus(user: ApiUser, lang: LangFn) {
|
||||
return lang('LastSeen.YesterdayAt', formatTime(wasOnlineDate));
|
||||
}
|
||||
|
||||
return lang('LastSeen.AtDate', formatFullDate(wasOnlineDate));
|
||||
return lang('LastSeen.AtDate', formatFullDate(lang, wasOnlineDate));
|
||||
}
|
||||
|
||||
case 'userStatusOnline': {
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
import { getTranslation } from './langProvider';
|
||||
import { LangFn } from '../hooks/useLang';
|
||||
|
||||
const WEEKDAYS_FULL = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'];
|
||||
const MONTHS_FULL = [
|
||||
@ -39,7 +39,7 @@ export function formatTime(datetime: number | Date) {
|
||||
return `${hours}:${minutes}`;
|
||||
}
|
||||
|
||||
export function formatPastTimeShort(datetime: number | Date) {
|
||||
export function formatPastTimeShort(lang: LangFn, datetime: number | Date) {
|
||||
const date = typeof datetime === 'number' ? new Date(datetime) : datetime;
|
||||
|
||||
const today = getDayStart(new Date());
|
||||
@ -50,45 +50,45 @@ export function formatPastTimeShort(datetime: number | Date) {
|
||||
const weekAgo = new Date(today);
|
||||
weekAgo.setDate(today.getDate() - 7);
|
||||
if (date >= weekAgo) {
|
||||
return getTranslation(`Weekday.Short${WEEKDAYS_FULL[date.getDay()]}`);
|
||||
return lang(`Weekday.Short${WEEKDAYS_FULL[date.getDay()]}`);
|
||||
}
|
||||
|
||||
const withYear = date.getFullYear() !== today.getFullYear();
|
||||
const format = (
|
||||
getTranslation(withYear ? 'formatDateScheduleYear' : 'formatDateSchedule')
|
||||
lang(withYear ? 'formatDateScheduleYear' : 'formatDateSchedule')
|
||||
|| (withYear ? 'd MMM yyyy' : 'd MMM')
|
||||
);
|
||||
|
||||
return formatDate(date, format);
|
||||
return formatDate(lang, date, format);
|
||||
}
|
||||
|
||||
export function formatFullDate(datetime: number | Date) {
|
||||
export function formatFullDate(lang: LangFn, datetime: number | Date) {
|
||||
const date = typeof datetime === 'number' ? new Date(datetime) : datetime;
|
||||
const format = getTranslation('formatterYearMax') || 'dd.MM.yyyy';
|
||||
const format = lang('formatterYearMax') || 'dd.MM.yyyy';
|
||||
|
||||
return formatDate(date, format);
|
||||
return formatDate(lang, date, format);
|
||||
}
|
||||
|
||||
export function formatMonthAndYear(date: Date, isShort = false) {
|
||||
const format = getTranslation(isShort ? 'formatterMonthYear2' : 'formatterMonthYear') || 'MMM yyyy';
|
||||
export function formatMonthAndYear(lang: LangFn, date: Date, isShort = false) {
|
||||
const format = lang(isShort ? 'formatterMonthYear2' : 'formatterMonthYear') || 'MMM yyyy';
|
||||
|
||||
return formatDate(date, format);
|
||||
return formatDate(lang, date, format);
|
||||
}
|
||||
|
||||
export function formatHumanDate(datetime: number | Date, isShort = false, noWeekdays = false) {
|
||||
export function formatHumanDate(lang: LangFn, datetime: number | Date, isShort = false, noWeekdays = false) {
|
||||
const date = typeof datetime === 'number' ? new Date(datetime) : datetime;
|
||||
|
||||
const today = getDayStart(new Date());
|
||||
|
||||
if (!noWeekdays) {
|
||||
if (toIsoString(date) === toIsoString(today)) {
|
||||
return (isShort ? lowerFirst : upperFirst)(getTranslation('Weekday.Today'));
|
||||
return (isShort ? lowerFirst : upperFirst)(lang('Weekday.Today'));
|
||||
}
|
||||
|
||||
const yesterday = new Date(today);
|
||||
yesterday.setDate(today.getDate() - 1);
|
||||
if (toIsoString(date) === toIsoString(yesterday)) {
|
||||
return (isShort ? lowerFirst : upperFirst)(getTranslation('Weekday.Yesterday'));
|
||||
return (isShort ? lowerFirst : upperFirst)(lang('Weekday.Yesterday'));
|
||||
}
|
||||
|
||||
const weekAgo = new Date(today);
|
||||
@ -98,8 +98,8 @@ export function formatHumanDate(datetime: number | Date, isShort = false, noWeek
|
||||
if (date >= weekAgo && date <= weekAhead) {
|
||||
const weekDay = WEEKDAYS_FULL[date.getDay()];
|
||||
return isShort
|
||||
? lowerFirst(getTranslation(`Weekday.Short${weekDay}`))
|
||||
: upperFirst(getTranslation(`Weekday.${weekDay}`));
|
||||
? lowerFirst(lang(`Weekday.Short${weekDay}`))
|
||||
: upperFirst(lang(`Weekday.${weekDay}`));
|
||||
}
|
||||
}
|
||||
|
||||
@ -107,29 +107,29 @@ export function formatHumanDate(datetime: number | Date, isShort = false, noWeek
|
||||
const formatKey = isShort
|
||||
? (withYear ? 'formatDateScheduleYear' : 'formatDateSchedule')
|
||||
: (withYear ? 'chatFullDate' : 'chatDate');
|
||||
const format = getTranslation(formatKey) || 'd MMMM yyyy';
|
||||
const format = lang(formatKey) || 'd MMMM yyyy';
|
||||
|
||||
return (isShort ? lowerFirst : upperFirst)(formatDate(date, format));
|
||||
return (isShort ? lowerFirst : upperFirst)(formatDate(lang, date, format));
|
||||
}
|
||||
|
||||
function formatDate(date: Date, format: string) {
|
||||
function formatDate(lang: LangFn, date: Date, format: string) {
|
||||
const day = date.getDate();
|
||||
const monthIndex = date.getMonth();
|
||||
|
||||
return format
|
||||
.replace('LLLL', getTranslation(MONTHS_FULL[monthIndex]))
|
||||
.replace('MMMM', getTranslation(`Month.Gen${MONTHS_FULL[monthIndex]}`))
|
||||
.replace('MMM', getTranslation(`Month.Short${MONTHS_FULL[monthIndex]}`))
|
||||
.replace('LLLL', lang(MONTHS_FULL[monthIndex]))
|
||||
.replace('MMMM', lang(`Month.Gen${MONTHS_FULL[monthIndex]}`))
|
||||
.replace('MMM', lang(`Month.Short${MONTHS_FULL[monthIndex]}`))
|
||||
.replace('MM', String(monthIndex + 1).padStart(2, '0'))
|
||||
.replace('dd', String(day).padStart(2, '0'))
|
||||
.replace('d', String(day))
|
||||
.replace('yyyy', String(date.getFullYear()));
|
||||
}
|
||||
|
||||
export function formatMediaDateTime(datetime: number | Date) {
|
||||
export function formatMediaDateTime(lang: LangFn, datetime: number | Date) {
|
||||
const date = typeof datetime === 'number' ? new Date(datetime) : datetime;
|
||||
|
||||
return `${formatHumanDate(date, true)}, ${formatTime(date)}`;
|
||||
return `${formatHumanDate(lang, date, true)}, ${formatTime(date)}`;
|
||||
}
|
||||
|
||||
export function formatMediaDuration(duration: number) {
|
||||
|
||||
@ -239,14 +239,14 @@ function getNotificationContent(chat: ApiChat, message: ApiMessage) {
|
||||
{ asPlain: true },
|
||||
) as string;
|
||||
} else {
|
||||
const senderName = getMessageSenderName(chat.id, messageSender);
|
||||
const senderName = getMessageSenderName(getTranslation, chat.id, messageSender);
|
||||
const summary = getMessageSummaryText(getTranslation, message);
|
||||
|
||||
body = senderName ? `${senderName}: ${summary}` : summary;
|
||||
}
|
||||
|
||||
return {
|
||||
title: getChatTitle(chat, privateChatUser),
|
||||
title: getChatTitle(getTranslation, chat, privateChatUser),
|
||||
body,
|
||||
};
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user