Localization: Remove legacy fallback strings (#6577)
This commit is contained in:
parent
bcb276d568
commit
e112d3d9ed
@ -637,8 +637,6 @@
|
|||||||
"PreviewSenderSendAudio_other" = "Send {count} Audios";
|
"PreviewSenderSendAudio_other" = "Send {count} Audios";
|
||||||
"PreviewSenderSendFile_one" = "Send File";
|
"PreviewSenderSendFile_one" = "Send File";
|
||||||
"PreviewSenderSendFile_other" = "Send {count} Files";
|
"PreviewSenderSendFile_other" = "Send {count} Files";
|
||||||
"PreviewDraggingAddItems_one" = "Add Item";
|
|
||||||
"PreviewDraggingAddItems_other" = "Add Items";
|
|
||||||
"Caption" = "Caption";
|
"Caption" = "Caption";
|
||||||
"CropperTitle" = "Drag to reposition";
|
"CropperTitle" = "Drag to reposition";
|
||||||
"CropperApply" = "Crop Image";
|
"CropperApply" = "Crop Image";
|
||||||
@ -1463,9 +1461,11 @@
|
|||||||
"ProfileBirthday" = "Birthday";
|
"ProfileBirthday" = "Birthday";
|
||||||
"ProfileBirthdayToday" = "Birthday today";
|
"ProfileBirthdayToday" = "Birthday today";
|
||||||
"ProfileBirthdayValue" = "{date}";
|
"ProfileBirthdayValue" = "{date}";
|
||||||
"ProfileBirthdayValueYear" = "{date} ({age} years old)";
|
"ProfileBirthdayValueAge_one" = "{date} ({age} year old)";
|
||||||
|
"ProfileBirthdayValueAge_other" = "{date} ({age} years old)";
|
||||||
"ProfileBirthdayTodayValue" = "🎂 {date}";
|
"ProfileBirthdayTodayValue" = "🎂 {date}";
|
||||||
"ProfileBirthdayTodayValueYear" = "🎂 {date} ({age} years old)";
|
"ProfileBirthdayTodayValueAge_one" = "🎂 {date} ({age} year old)";
|
||||||
|
"ProfileBirthdayTodayValueAge_other" = "🎂 {date} ({age} years old)";
|
||||||
"ProfileMenuSetMainTab" = "Set as Main Tab";
|
"ProfileMenuSetMainTab" = "Set as Main Tab";
|
||||||
"ProfileItemSubscribers" = "Subscribers";
|
"ProfileItemSubscribers" = "Subscribers";
|
||||||
"MonetizationInfoTONTitle" = "What is 💎 TON?";
|
"MonetizationInfoTONTitle" = "What is 💎 TON?";
|
||||||
@ -2535,3 +2535,35 @@
|
|||||||
"BotReadTextFromClipboardTitle" = "Clipboard Access";
|
"BotReadTextFromClipboardTitle" = "Clipboard Access";
|
||||||
"BotReadTextFromClipboardDescription" = "{bot} wants to read the contents of your clipboard. Do you want to continue?";
|
"BotReadTextFromClipboardDescription" = "{bot} wants to read the contents of your clipboard. Do you want to continue?";
|
||||||
"BotReadTextFromClipboardConfirm" = "Allow";
|
"BotReadTextFromClipboardConfirm" = "Allow";
|
||||||
|
"ChatTypePrivate" = "Private Chat";
|
||||||
|
"ChatTypeGroup" = "Group";
|
||||||
|
"ChatTypeChannel" = "Channel";
|
||||||
|
"ChatTypeFallback" = "Chat";
|
||||||
|
"ChatInfoNoMessages" = "No messages";
|
||||||
|
"GroupStatusWithOnline" = "{status}, {onlineCount}";
|
||||||
|
"AttachmentMenuSendAsMedia" = "Send as Media";
|
||||||
|
"AttachmentMenuSendAllAsMedia" = "Send All as Media";
|
||||||
|
"AttachmentMenuSendAsFiles" = "Send as Files";
|
||||||
|
"AttachmentMenuSendAllAsFiles" = "Send All as Files";
|
||||||
|
"AttachmentMenuGroupAllMedia" = "Group All Media";
|
||||||
|
"AttachmentMenuUngroupAllMedia" = "Ungroup All Media";
|
||||||
|
"AttachmentMenuEnableSpoiler" = "Enable Spoiler";
|
||||||
|
"AttachmentMenuDisableSpoiler" = "Disable Spoiler";
|
||||||
|
"AttachmentReplacePhoto_one" = "Replace Photo";
|
||||||
|
"AttachmentReplacePhoto_other" = "Replace {count} Photos";
|
||||||
|
"AttachmentReplaceVideo_one" = "Replace Video";
|
||||||
|
"AttachmentReplaceVideo_other" = "Replace {count} Videos";
|
||||||
|
"AttachmentReplaceAudio_one" = "Replace Audio";
|
||||||
|
"AttachmentReplaceAudio_other" = "Replace {count} Audios";
|
||||||
|
"AttachmentReplaceFile_one" = "Replace File";
|
||||||
|
"AttachmentReplaceFile_other" = "Replace {count} Files";
|
||||||
|
"AttachmentSendPhoto_one" = "Send Photo";
|
||||||
|
"AttachmentSendPhoto_other" = "Send {count} Photos";
|
||||||
|
"AttachmentSendVideo_one" = "Send Video";
|
||||||
|
"AttachmentSendVideo_other" = "Send {count} Videos";
|
||||||
|
"AttachmentSendAudio_one" = "Send Audio";
|
||||||
|
"AttachmentSendAudio_other" = "Send {count} Audios";
|
||||||
|
"AttachmentSendFile_one" = "Send File";
|
||||||
|
"AttachmentSendFile_other" = "Send {count} Files";
|
||||||
|
"AttachmentDragAddItems" = "Add Items";
|
||||||
|
"AttachmentCaptionPlaceholder" = "Add a caption...";
|
||||||
|
|||||||
@ -8,7 +8,7 @@ import type { IconName } from '../../types/icons';
|
|||||||
import { MediaViewerOrigin, type StoryViewerOrigin, type ThreadId } from '../../types';
|
import { MediaViewerOrigin, type StoryViewerOrigin, type ThreadId } from '../../types';
|
||||||
|
|
||||||
import {
|
import {
|
||||||
getChatTypeString,
|
getChatTypeLangKey,
|
||||||
getGroupStatus,
|
getGroupStatus,
|
||||||
getMainUsername,
|
getMainUsername,
|
||||||
isChatSuperGroup,
|
isChatSuperGroup,
|
||||||
@ -29,7 +29,6 @@ import renderText from './helpers/renderText';
|
|||||||
|
|
||||||
import useLang from '../../hooks/useLang';
|
import useLang from '../../hooks/useLang';
|
||||||
import useLastCallback from '../../hooks/useLastCallback';
|
import useLastCallback from '../../hooks/useLastCallback';
|
||||||
import useOldLang from '../../hooks/useOldLang';
|
|
||||||
|
|
||||||
import Transition from '../ui/Transition';
|
import Transition from '../ui/Transition';
|
||||||
import Avatar from './Avatar';
|
import Avatar from './Avatar';
|
||||||
@ -117,7 +116,6 @@ const GroupChatInfo = ({
|
|||||||
|
|
||||||
const chat = !withMonoforumStatus && monoforumChannel ? monoforumChannel : realChat;
|
const chat = !withMonoforumStatus && monoforumChannel ? monoforumChannel : realChat;
|
||||||
|
|
||||||
const oldLang = useOldLang();
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const isSuperGroup = chat && isChatSuperGroup(chat);
|
const isSuperGroup = chat && isChatSuperGroup(chat);
|
||||||
@ -155,7 +153,7 @@ const GroupChatInfo = ({
|
|||||||
function renderStatusOrTyping() {
|
function renderStatusOrTyping() {
|
||||||
if (withUpdatingStatus && !areMessagesLoaded && !isRestricted) {
|
if (withUpdatingStatus && !areMessagesLoaded && !isRestricted) {
|
||||||
return (
|
return (
|
||||||
<DotAnimation className="status" content={oldLang('Updating')} />
|
<DotAnimation className="status" content={lang('Updating')} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -199,7 +197,9 @@ const GroupChatInfo = ({
|
|||||||
activeKey={messagesCount !== undefined ? 1 : 2}
|
activeKey={messagesCount !== undefined ? 1 : 2}
|
||||||
className="message-count-transition"
|
className="message-count-transition"
|
||||||
>
|
>
|
||||||
{messagesCount !== undefined ? oldLang('messages', messagesCount, 'i') : oldLang('lng_forum_no_messages')}
|
{messagesCount !== undefined
|
||||||
|
? lang('Messages', { count: messagesCount }, { pluralValue: messagesCount })
|
||||||
|
: lang('ChatInfoNoMessages')}
|
||||||
</Transition>
|
</Transition>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
@ -207,18 +207,22 @@ const GroupChatInfo = ({
|
|||||||
|
|
||||||
if (withChatType) {
|
if (withChatType) {
|
||||||
return (
|
return (
|
||||||
<span className="status" dir="auto">{oldLang(getChatTypeString(chat))}</span>
|
<span className="status" dir="auto">{lang(getChatTypeLangKey(chat))}</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
const groupStatus = getGroupStatus(oldLang, chat);
|
const groupStatusElement = <span className="group-status">{getGroupStatus(lang, chat)}</span>;
|
||||||
const onlineStatus = onlineCount ? `, ${oldLang('OnlineCount', onlineCount, 'i')}` : undefined;
|
const onlineStatus = onlineCount ? lang('OnlineCount', { count: onlineCount }, { pluralValue: onlineCount })
|
||||||
|
: undefined;
|
||||||
|
const onlineStatusElement = onlineStatus ? <span className="online-status">{onlineStatus}</span> : undefined;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<span className="status">
|
<span className="status">
|
||||||
{mainUsername && <span className="handle withStatus">{mainUsername}</span>}
|
{mainUsername && <span className="handle withStatus">{mainUsername}</span>}
|
||||||
<span className="group-status">{groupStatus}</span>
|
{!onlineStatusElement ? groupStatusElement
|
||||||
{onlineStatus && <span className="online-status">{onlineStatus}</span>}
|
: lang('GroupStatusWithOnline', {
|
||||||
|
status: groupStatusElement, onlineCount: onlineStatusElement,
|
||||||
|
}, { withNodes: true })}
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -184,7 +184,7 @@ const PrivateChatInfo = ({
|
|||||||
|
|
||||||
if (withUpdatingStatus && !areMessagesLoaded) {
|
if (withUpdatingStatus && !areMessagesLoaded) {
|
||||||
return (
|
return (
|
||||||
<DotAnimation className="status" content={oldLang('Updating')} />
|
<DotAnimation className="status" content={lang('Updating')} />
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +213,9 @@ const PrivateChatInfo = ({
|
|||||||
activeKey={messagesCount !== undefined ? 1 : 2}
|
activeKey={messagesCount !== undefined ? 1 : 2}
|
||||||
className="message-count-transition"
|
className="message-count-transition"
|
||||||
>
|
>
|
||||||
{messagesCount !== undefined ? oldLang('messages', messagesCount, 'i') : oldLang('lng_forum_no_messages')}
|
{messagesCount !== undefined
|
||||||
|
? lang('Messages', { count: messagesCount }, { pluralValue: messagesCount })
|
||||||
|
: lang('ChatInfoNoMessages')}
|
||||||
</Transition>
|
</Transition>
|
||||||
</span>
|
</span>
|
||||||
);
|
);
|
||||||
|
|||||||
@ -220,7 +220,7 @@ const ChatOrUserPicker = ({
|
|||||||
if (!peer) return undefined;
|
if (!peer) return undefined;
|
||||||
if (peer.id === currentUserId) return [oldLang('SavedMessagesInfo')];
|
if (peer.id === currentUserId) return [oldLang('SavedMessagesInfo')];
|
||||||
if (isApiPeerChat(peer)) {
|
if (isApiPeerChat(peer)) {
|
||||||
return [getGroupStatus(oldLang, peer)];
|
return [getGroupStatus(lang, peer)];
|
||||||
}
|
}
|
||||||
|
|
||||||
const userStatus = selectUserStatus(global, peer.id);
|
const userStatus = selectUserStatus(global, peer.id);
|
||||||
@ -262,7 +262,7 @@ const ChatOrUserPicker = ({
|
|||||||
onClick={() => handleClick(id)}
|
onClick={() => handleClick(id)}
|
||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}, [currentUserId, oldLang, viewportOffset]);
|
}, [currentUserId, oldLang, lang, viewportOffset]);
|
||||||
|
|
||||||
function renderTopicList() {
|
function renderTopicList() {
|
||||||
return (
|
return (
|
||||||
|
|||||||
@ -17,6 +17,7 @@ import { buildCollectionByKey } from '../../../util/iteratees';
|
|||||||
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
import { MEMO_EMPTY_ARRAY } from '../../../util/memo';
|
||||||
|
|
||||||
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
|
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
|
||||||
|
import useLang from '../../../hooks/useLang';
|
||||||
import useLastCallback from '../../../hooks/useLastCallback';
|
import useLastCallback from '../../../hooks/useLastCallback';
|
||||||
import useOldLang from '../../../hooks/useOldLang';
|
import useOldLang from '../../../hooks/useOldLang';
|
||||||
|
|
||||||
@ -113,7 +114,8 @@ const PeerPicker = <CategoryType extends string = CustomPeerType>({
|
|||||||
onLoadMore,
|
onLoadMore,
|
||||||
...optionalProps
|
...optionalProps
|
||||||
}: OwnProps<CategoryType>) => {
|
}: OwnProps<CategoryType>) => {
|
||||||
const lang = useOldLang();
|
const oldLang = useOldLang();
|
||||||
|
const lang = useLang();
|
||||||
|
|
||||||
const allowMultiple = optionalProps.allowMultiple;
|
const allowMultiple = optionalProps.allowMultiple;
|
||||||
const lockedSelectedIds = allowMultiple ? optionalProps.lockedSelectedIds : undefined;
|
const lockedSelectedIds = allowMultiple ? optionalProps.lockedSelectedIds : undefined;
|
||||||
@ -285,14 +287,14 @@ const PeerPicker = <CategoryType extends string = CustomPeerType>({
|
|||||||
|
|
||||||
const userStatus = selectUserStatus(global, peer.id);
|
const userStatus = selectUserStatus(global, peer.id);
|
||||||
return [
|
return [
|
||||||
getUserStatus(lang, peer, userStatus),
|
getUserStatus(oldLang, peer, userStatus),
|
||||||
buildClassName(isUserOnline(peer, userStatus, true) && styles.onlineStatus),
|
buildClassName(isUserOnline(peer, userStatus, true) && styles.onlineStatus),
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
||||||
if (withPeerTypes) {
|
if (withPeerTypes) {
|
||||||
const langKey = getPeerTypeKey(peer);
|
const langKey = getPeerTypeKey(peer);
|
||||||
return langKey && [lang(langKey)];
|
return langKey && [oldLang(langKey)];
|
||||||
}
|
}
|
||||||
|
|
||||||
return undefined;
|
return undefined;
|
||||||
@ -326,26 +328,26 @@ const PeerPicker = <CategoryType extends string = CustomPeerType>({
|
|||||||
/>
|
/>
|
||||||
);
|
);
|
||||||
}, [
|
}, [
|
||||||
categoriesByType, forceShowSelf, isViewOnly, itemClassName, itemInputType, lang, lockedSelectedIdsSet,
|
categoriesByType, forceShowSelf, isViewOnly, itemClassName, itemInputType, oldLang, lockedSelectedIdsSet,
|
||||||
lockedUnselectedIdsSet, lockedUnselectedSubtitle, onDisabledClick, selectedCategories, selectedIds,
|
lockedUnselectedIdsSet, lockedUnselectedSubtitle, onDisabledClick, selectedCategories, selectedIds,
|
||||||
withPeerTypes, withStatus, withPeerUsernames,
|
withPeerTypes, withStatus, withPeerUsernames, lang,
|
||||||
]);
|
]);
|
||||||
|
|
||||||
const beforeChildren = useMemo(() => {
|
const beforeChildren = useMemo(() => {
|
||||||
if (!categories?.length) return undefined;
|
if (!categories?.length) return undefined;
|
||||||
return (
|
return (
|
||||||
<div key="categories">
|
<div key="categories">
|
||||||
{categoryPlaceholderKey && <div className={styles.pickerCategoryTitle}>{lang(categoryPlaceholderKey)}</div>}
|
{categoryPlaceholderKey && <div className={styles.pickerCategoryTitle}>{oldLang(categoryPlaceholderKey)}</div>}
|
||||||
{categories?.map((category) => renderItem(category.type, true))}
|
{categories?.map((category) => renderItem(category.type, true))}
|
||||||
<div className={styles.pickerCategoryTitle}>{lang('FilterChats')}</div>
|
<div className={styles.pickerCategoryTitle}>{oldLang('FilterChats')}</div>
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}, [categories, categoryPlaceholderKey, lang, renderItem]);
|
}, [categories, categoryPlaceholderKey, oldLang, renderItem]);
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={buildClassName(styles.container, className)}>
|
<div className={buildClassName(styles.container, className)}>
|
||||||
{isSearchable && (
|
{isSearchable && (
|
||||||
<div className={buildClassName(styles.header, 'custom-scroll')} dir={lang.isRtl ? 'rtl' : undefined}>
|
<div className={buildClassName(styles.header, 'custom-scroll')} dir={oldLang.isRtl ? 'rtl' : undefined}>
|
||||||
{selectedCategories?.map((category) => (
|
{selectedCategories?.map((category) => (
|
||||||
<PeerChip
|
<PeerChip
|
||||||
className={styles.peerChip}
|
className={styles.peerChip}
|
||||||
@ -382,7 +384,7 @@ const PeerPicker = <CategoryType extends string = CustomPeerType>({
|
|||||||
ref={inputRef}
|
ref={inputRef}
|
||||||
value={filterValue}
|
value={filterValue}
|
||||||
onChange={handleFilterChange}
|
onChange={handleFilterChange}
|
||||||
placeholder={filterPlaceholder || lang('SelectChat')}
|
placeholder={filterPlaceholder || oldLang('SelectChat')}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
)}
|
)}
|
||||||
|
|||||||
@ -140,7 +140,7 @@ const UserBirthday = ({
|
|||||||
const value = useMemo(() => {
|
const value = useMemo(() => {
|
||||||
if (age) {
|
if (age) {
|
||||||
return lang(
|
return lang(
|
||||||
`ProfileBirthday${isToday ? 'Today' : ''}ValueYear`,
|
`ProfileBirthday${isToday ? 'Today' : ''}ValueAge`,
|
||||||
{ date: formattedDate, age },
|
{ date: formattedDate, age },
|
||||||
{ pluralValue: age },
|
{ pluralValue: age },
|
||||||
);
|
);
|
||||||
|
|||||||
@ -1,6 +1,4 @@
|
|||||||
import type React from '../../../lib/teact/teact';
|
import { type FC, memo, useEffect, useMemo, useRef, useState } from '../../../lib/teact/teact';
|
||||||
import type { FC } from '../../../lib/teact/teact';
|
|
||||||
import { memo, useEffect, useMemo, useRef, useState } from '../../../lib/teact/teact';
|
|
||||||
import { getActions, withGlobal } from '../../../global';
|
import { getActions, withGlobal } from '../../../global';
|
||||||
|
|
||||||
import type { ApiAttachment, ApiChatMember, ApiMessage, ApiSticker } from '../../../api/types';
|
import type { ApiAttachment, ApiChatMember, ApiMessage, ApiSticker } from '../../../api/types';
|
||||||
@ -37,7 +35,6 @@ import useFlag from '../../../hooks/useFlag';
|
|||||||
import useGetSelectionRange from '../../../hooks/useGetSelectionRange';
|
import useGetSelectionRange from '../../../hooks/useGetSelectionRange';
|
||||||
import useLang from '../../../hooks/useLang';
|
import useLang from '../../../hooks/useLang';
|
||||||
import useLastCallback from '../../../hooks/useLastCallback';
|
import useLastCallback from '../../../hooks/useLastCallback';
|
||||||
import useOldLang from '../../../hooks/useOldLang';
|
|
||||||
import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated';
|
import usePreviousDeprecated from '../../../hooks/usePreviousDeprecated';
|
||||||
import useResizeObserver from '../../../hooks/useResizeObserver';
|
import useResizeObserver from '../../../hooks/useResizeObserver';
|
||||||
import useScrolledState from '../../../hooks/useScrolledState';
|
import useScrolledState from '../../../hooks/useScrolledState';
|
||||||
@ -74,6 +71,9 @@ export type OwnProps = {
|
|||||||
shouldForceAsFile?: boolean;
|
shouldForceAsFile?: boolean;
|
||||||
isForCurrentMessageList?: boolean;
|
isForCurrentMessageList?: boolean;
|
||||||
forceDarkTheme?: boolean;
|
forceDarkTheme?: boolean;
|
||||||
|
canScheduleUntilOnline?: boolean;
|
||||||
|
canSchedule?: boolean;
|
||||||
|
paidMessagesStars?: number;
|
||||||
onCaptionUpdate: (html: string) => void;
|
onCaptionUpdate: (html: string) => void;
|
||||||
onSend: (sendCompressed: boolean, sendGrouped: boolean, isInvertedMedia?: true) => void;
|
onSend: (sendCompressed: boolean, sendGrouped: boolean, isInvertedMedia?: true) => void;
|
||||||
onFileAppend: (files: File[], isSpoiler?: boolean) => void;
|
onFileAppend: (files: File[], isSpoiler?: boolean) => void;
|
||||||
@ -84,10 +84,7 @@ export type OwnProps = {
|
|||||||
onCustomEmojiSelect: (emoji: ApiSticker) => void;
|
onCustomEmojiSelect: (emoji: ApiSticker) => void;
|
||||||
onRemoveSymbol: VoidFunction;
|
onRemoveSymbol: VoidFunction;
|
||||||
onEmojiSelect: (emoji: string) => void;
|
onEmojiSelect: (emoji: string) => void;
|
||||||
canScheduleUntilOnline?: boolean;
|
|
||||||
canSchedule?: boolean;
|
|
||||||
onSendWhenOnline?: NoneToVoidFunction;
|
onSendWhenOnline?: NoneToVoidFunction;
|
||||||
paidMessagesStars?: number;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
type StateProps = {
|
type StateProps = {
|
||||||
@ -109,7 +106,7 @@ const DROP_LEAVE_TIMEOUT_MS = 150;
|
|||||||
const MAX_LEFT_CHARS_TO_SHOW = 100;
|
const MAX_LEFT_CHARS_TO_SHOW = 100;
|
||||||
const CLOSE_MENU_ANIMATION_DURATION = 200;
|
const CLOSE_MENU_ANIMATION_DURATION = 200;
|
||||||
|
|
||||||
const AttachmentModal: FC<OwnProps & StateProps> = ({
|
const AttachmentModal = ({
|
||||||
chatId,
|
chatId,
|
||||||
threadId,
|
threadId,
|
||||||
attachments,
|
attachments,
|
||||||
@ -134,6 +131,9 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
shouldForceAsFile,
|
shouldForceAsFile,
|
||||||
isForCurrentMessageList,
|
isForCurrentMessageList,
|
||||||
forceDarkTheme,
|
forceDarkTheme,
|
||||||
|
canScheduleUntilOnline,
|
||||||
|
canSchedule,
|
||||||
|
paidMessagesStars,
|
||||||
onAttachmentsUpdate,
|
onAttachmentsUpdate,
|
||||||
onCaptionUpdate,
|
onCaptionUpdate,
|
||||||
onSend,
|
onSend,
|
||||||
@ -144,16 +144,12 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
onCustomEmojiSelect,
|
onCustomEmojiSelect,
|
||||||
onRemoveSymbol,
|
onRemoveSymbol,
|
||||||
onEmojiSelect,
|
onEmojiSelect,
|
||||||
canScheduleUntilOnline,
|
|
||||||
canSchedule,
|
|
||||||
onSendWhenOnline,
|
onSendWhenOnline,
|
||||||
paidMessagesStars,
|
}: OwnProps & StateProps) => {
|
||||||
}) => {
|
|
||||||
const ref = useRef<HTMLDivElement>();
|
const ref = useRef<HTMLDivElement>();
|
||||||
const svgRef = useRef<SVGSVGElement>();
|
const svgRef = useRef<SVGSVGElement>();
|
||||||
const { addRecentCustomEmoji, addRecentEmoji, updateAttachmentSettings } = getActions();
|
const { addRecentCustomEmoji, addRecentEmoji, updateAttachmentSettings } = getActions();
|
||||||
|
|
||||||
const oldLang = useOldLang();
|
|
||||||
const lang = useLang();
|
const lang = useLang();
|
||||||
|
|
||||||
const mainButtonRef = useRef<HTMLButtonElement>();
|
const mainButtonRef = useRef<HTMLButtonElement>();
|
||||||
@ -444,7 +440,7 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
requestMutation(() => {
|
requestMutation(() => {
|
||||||
input.style.setProperty('--margin-for-scrollbar', `${width}px`);
|
input.style.setProperty('--margin-for-scrollbar', `${width}px`);
|
||||||
});
|
});
|
||||||
}, [oldLang, isOpen]);
|
}, [lang, isOpen]);
|
||||||
|
|
||||||
const MoreMenuButton: FC<{ onTrigger: () => void; isOpen?: boolean }> = useMemo(() => {
|
const MoreMenuButton: FC<{ onTrigger: () => void; isOpen?: boolean }> = useMemo(() => {
|
||||||
return ({ onTrigger, isOpen: isMenuOpen }) => (
|
return ({ onTrigger, isOpen: isMenuOpen }) => (
|
||||||
@ -515,13 +511,29 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
let title = '';
|
let title = '';
|
||||||
const attachmentsLength = renderingAttachments.length;
|
const attachmentsLength = renderingAttachments.length;
|
||||||
if (areAllPhotos) {
|
if (areAllPhotos) {
|
||||||
title = oldLang(isEditing ? 'EditMessageReplacePhoto' : 'PreviewSender.SendPhoto', attachmentsLength, 'i');
|
title = lang(
|
||||||
|
`Attachment${isEditing ? 'Replace' : 'Send'}Photo`,
|
||||||
|
{ count: attachmentsLength },
|
||||||
|
{ pluralValue: attachmentsLength },
|
||||||
|
);
|
||||||
} else if (areAllVideos) {
|
} else if (areAllVideos) {
|
||||||
title = oldLang(isEditing ? 'EditMessageReplaceVideo' : 'PreviewSender.SendVideo', attachmentsLength, 'i');
|
title = lang(
|
||||||
|
`Attachment${isEditing ? 'Replace' : 'Send'}Video`,
|
||||||
|
{ count: attachmentsLength },
|
||||||
|
{ pluralValue: attachmentsLength },
|
||||||
|
);
|
||||||
} else if (areAllAudios) {
|
} else if (areAllAudios) {
|
||||||
title = oldLang(isEditing ? 'EditMessageReplaceAudio' : 'PreviewSender.SendAudio', attachmentsLength, 'i');
|
title = lang(
|
||||||
|
`Attachment${isEditing ? 'Replace' : 'Send'}Audio`,
|
||||||
|
{ count: attachmentsLength },
|
||||||
|
{ pluralValue: attachmentsLength },
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
title = oldLang(isEditing ? 'EditMessageReplaceFile' : 'PreviewSender.SendFile', attachmentsLength, 'i');
|
title = lang(
|
||||||
|
`Attachment${isEditing ? 'Replace' : 'Send'}File`,
|
||||||
|
{ count: attachmentsLength },
|
||||||
|
{ pluralValue: attachmentsLength },
|
||||||
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderHeader() {
|
function renderHeader() {
|
||||||
@ -548,7 +560,7 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
positionX="right"
|
positionX="right"
|
||||||
>
|
>
|
||||||
{Boolean(!editingMessage) && (
|
{Boolean(!editingMessage) && (
|
||||||
<MenuItem icon="add" onClick={handleDocumentSelect}>{oldLang('Add')}</MenuItem>
|
<MenuItem icon="add" onClick={handleDocumentSelect}>{lang('Add')}</MenuItem>
|
||||||
)}
|
)}
|
||||||
{hasMedia && (
|
{hasMedia && (
|
||||||
<>
|
<>
|
||||||
@ -569,12 +581,12 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
!shouldForceAsFile && !shouldForceCompression && (isSendingCompressed ? (
|
!shouldForceAsFile && !shouldForceCompression && (isSendingCompressed ? (
|
||||||
|
|
||||||
<MenuItem icon="document" onClick={handleToggleShouldCompress}>
|
<MenuItem icon="document" onClick={handleToggleShouldCompress}>
|
||||||
{oldLang(isMultiple ? 'Attachment.SendAsFiles' : 'Attachment.SendAsFile')}
|
{lang(isMultiple ? 'AttachmentMenuSendAllAsFiles' : 'AttachmentMenuSendAsFiles')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
) : (
|
) : (
|
||||||
|
|
||||||
<MenuItem icon="photo" onClick={handleToggleShouldCompress}>
|
<MenuItem icon="photo" onClick={handleToggleShouldCompress}>
|
||||||
{isMultiple ? 'Send All as Media' : 'Send as Media'}
|
{lang(isMultiple ? 'AttachmentMenuSendAllAsMedia' : 'AttachmentMenuSendAsMedia')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
@ -589,11 +601,11 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
{isSendingCompressed && hasAnySpoilerable && Boolean(!editingMessage) && (
|
{isSendingCompressed && hasAnySpoilerable && Boolean(!editingMessage) && (
|
||||||
hasSpoiler ? (
|
hasSpoiler ? (
|
||||||
<MenuItem icon="spoiler-disable" onClick={handleDisableSpoilers}>
|
<MenuItem icon="spoiler-disable" onClick={handleDisableSpoilers}>
|
||||||
{oldLang('Attachment.DisableSpoiler')}
|
{lang('AttachmentMenuDisableSpoiler')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
) : (
|
) : (
|
||||||
<MenuItem icon="spoiler" onClick={handleEnableSpoilers}>
|
<MenuItem icon="spoiler" onClick={handleEnableSpoilers}>
|
||||||
{oldLang('Attachment.EnableSpoiler')}
|
{lang('AttachmentMenuEnableSpoiler')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
@ -606,12 +618,12 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
|
|
||||||
onClick={() => setShouldSendGrouped(false)}
|
onClick={() => setShouldSendGrouped(false)}
|
||||||
>
|
>
|
||||||
Ungroup All Media
|
{lang('AttachmentMenuUngroupAllMedia')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
) : (
|
) : (
|
||||||
|
|
||||||
<MenuItem icon="grouped" onClick={() => setShouldSendGrouped(true)}>
|
<MenuItem icon="grouped" onClick={() => setShouldSendGrouped(true)}>
|
||||||
Group All Media
|
{lang('AttachmentMenuGroupAllMedia')}
|
||||||
</MenuItem>
|
</MenuItem>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
@ -629,7 +641,7 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
className: styles.sendButtonStar,
|
className: styles.sendButtonStar,
|
||||||
asFont: true,
|
asFont: true,
|
||||||
},
|
},
|
||||||
) : oldLang('Send');
|
) : lang('Send');
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Modal
|
<Modal
|
||||||
@ -655,7 +667,7 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
onDragOver={handleDragOver}
|
onDragOver={handleDragOver}
|
||||||
onDragLeave={handleDragLeave}
|
onDragLeave={handleDragLeave}
|
||||||
onClick={unmarkHovered}
|
onClick={unmarkHovered}
|
||||||
data-attach-description={oldLang('Preview.Dragging.AddItems', 10)}
|
data-attach-description={lang('AttachmentDragAddItems')}
|
||||||
data-dropzone
|
data-dropzone
|
||||||
>
|
>
|
||||||
<svg className={styles.dropOutlineContainer}>
|
<svg className={styles.dropOutlineContainer}>
|
||||||
@ -740,7 +752,7 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
isActive={isOpen}
|
isActive={isOpen}
|
||||||
getHtml={getHtml}
|
getHtml={getHtml}
|
||||||
editableInputId={EDITABLE_INPUT_MODAL_ID}
|
editableInputId={EDITABLE_INPUT_MODAL_ID}
|
||||||
placeholder={oldLang('AddCaption')}
|
placeholder={lang('AttachmentCaptionPlaceholder')}
|
||||||
onUpdate={onCaptionUpdate}
|
onUpdate={onCaptionUpdate}
|
||||||
onSend={handleSendClick}
|
onSend={handleSendClick}
|
||||||
onScroll={handleCaptionScroll}
|
onScroll={handleCaptionScroll}
|
||||||
@ -757,8 +769,8 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
|
|||||||
onClick={handleSendClick}
|
onClick={handleSendClick}
|
||||||
onContextMenu={canShowCustomSendMenu ? handleContextMenu : undefined}
|
onContextMenu={canShowCustomSendMenu ? handleContextMenu : undefined}
|
||||||
>
|
>
|
||||||
{shouldSchedule && !editingMessage ? oldLang('Next')
|
{shouldSchedule && !editingMessage ? lang('Next')
|
||||||
: editingMessage ? oldLang('Save') : buttonSendCaption}
|
: editingMessage ? lang('Save') : buttonSendCaption}
|
||||||
</Button>
|
</Button>
|
||||||
{canShowCustomSendMenu && (
|
{canShowCustomSendMenu && (
|
||||||
<CustomSendMenu
|
<CustomSendMenu
|
||||||
|
|||||||
@ -147,7 +147,7 @@ addCallback((global: GlobalState) => {
|
|||||||
|
|
||||||
const performanceType = selectPerformanceSettings(global);
|
const performanceType = selectPerformanceSettings(global);
|
||||||
|
|
||||||
void oldSetLanguage(language as LangCode, undefined, true);
|
void oldSetLanguage(language as LangCode, undefined);
|
||||||
|
|
||||||
requestMutation(() => {
|
requestMutation(() => {
|
||||||
document.documentElement.style.setProperty(
|
document.documentElement.style.setProperty(
|
||||||
|
|||||||
@ -15,6 +15,7 @@ import type { OldLangFn } from '../../hooks/useOldLang';
|
|||||||
import type {
|
import type {
|
||||||
CustomPeer, ThreadId,
|
CustomPeer, ThreadId,
|
||||||
} from '../../types';
|
} from '../../types';
|
||||||
|
import type { RegularLangKey } from '../../types/language';
|
||||||
import type { LangFn } from '../../util/localization';
|
import type { LangFn } from '../../util/localization';
|
||||||
import { MAIN_THREAD_ID } from '../../api/types';
|
import { MAIN_THREAD_ID } from '../../api/types';
|
||||||
|
|
||||||
@ -69,17 +70,17 @@ export function isAnonymousForwardsChat(chatId: string) {
|
|||||||
return chatId === ANONYMOUS_USER_ID;
|
return chatId === ANONYMOUS_USER_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getChatTypeString(chat: ApiChat) {
|
export function getChatTypeLangKey(chat: ApiChat): RegularLangKey {
|
||||||
switch (chat.type) {
|
switch (chat.type) {
|
||||||
case 'chatTypePrivate':
|
case 'chatTypePrivate':
|
||||||
return 'PrivateChat';
|
return 'ChatTypePrivate';
|
||||||
case 'chatTypeBasicGroup':
|
case 'chatTypeBasicGroup':
|
||||||
case 'chatTypeSuperGroup':
|
case 'chatTypeSuperGroup':
|
||||||
return 'AccDescrGroup';
|
return 'ChatTypeGroup';
|
||||||
case 'chatTypeChannel':
|
case 'chatTypeChannel':
|
||||||
return 'AccDescrChannel';
|
return 'ChatTypeChannel';
|
||||||
default:
|
default:
|
||||||
return 'Chat';
|
return 'ChatTypeFallback';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -396,23 +397,24 @@ export function getIsSavedDialog(chatId: string, threadId: ThreadId | undefined,
|
|||||||
return chatId === currentUserId && threadId !== MAIN_THREAD_ID;
|
return chatId === currentUserId && threadId !== MAIN_THREAD_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getGroupStatus(lang: OldLangFn, chat: ApiChat) {
|
export function getGroupStatus(lang: LangFn, chat: ApiChat) {
|
||||||
const chatTypeString = lang(getChatTypeString(chat));
|
const chatTypeKey = getChatTypeLangKey(chat);
|
||||||
|
const isChannel = isChatChannel(chat);
|
||||||
const { membersCount } = chat;
|
const { membersCount } = chat;
|
||||||
|
|
||||||
const global = getGlobal();
|
const global = getGlobal();
|
||||||
const isRestricted = selectIsChatRestricted(global, chat.id);
|
const isRestricted = selectIsChatRestricted(global, chat.id);
|
||||||
if (isRestricted) {
|
if (isRestricted) {
|
||||||
return chatTypeString === 'Channel' ? 'channel is inaccessible' : 'group is inaccessible';
|
return isChannel ? lang('ChannelInaccessible') : lang('GroupInaccessible');
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!membersCount) {
|
if (!membersCount) {
|
||||||
return chatTypeString;
|
return lang(chatTypeKey);
|
||||||
}
|
}
|
||||||
|
|
||||||
return chatTypeString === 'Channel'
|
return isChannel
|
||||||
? lang('Subscribers', membersCount, 'i')
|
? lang('Subscribers', { count: membersCount }, { pluralValue: membersCount })
|
||||||
: lang('Members', membersCount, 'i');
|
: lang('NMembers', { count: membersCount }, { pluralValue: membersCount });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getCustomPeerFromInvite(invite: ApiChatInviteInfo): CustomPeer {
|
export function getCustomPeerFromInvite(invite: ApiChatInviteInfo): CustomPeer {
|
||||||
|
|||||||
60
src/types/language.d.ts
vendored
60
src/types/language.d.ts
vendored
@ -1877,6 +1877,21 @@ export interface LangPair {
|
|||||||
'SettingsBirthday': undefined;
|
'SettingsBirthday': undefined;
|
||||||
'BotReadTextFromClipboardTitle': undefined;
|
'BotReadTextFromClipboardTitle': undefined;
|
||||||
'BotReadTextFromClipboardConfirm': undefined;
|
'BotReadTextFromClipboardConfirm': undefined;
|
||||||
|
'ChatTypePrivate': undefined;
|
||||||
|
'ChatTypeGroup': undefined;
|
||||||
|
'ChatTypeChannel': undefined;
|
||||||
|
'ChatTypeFallback': undefined;
|
||||||
|
'ChatInfoNoMessages': undefined;
|
||||||
|
'AttachmentMenuSendAsMedia': undefined;
|
||||||
|
'AttachmentMenuSendAllAsMedia': undefined;
|
||||||
|
'AttachmentMenuSendAsFiles': undefined;
|
||||||
|
'AttachmentMenuSendAllAsFiles': undefined;
|
||||||
|
'AttachmentMenuGroupAllMedia': undefined;
|
||||||
|
'AttachmentMenuUngroupAllMedia': undefined;
|
||||||
|
'AttachmentMenuEnableSpoiler': undefined;
|
||||||
|
'AttachmentMenuDisableSpoiler': undefined;
|
||||||
|
'AttachmentDragAddItems': undefined;
|
||||||
|
'AttachmentCaptionPlaceholder': undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LangPairWithVariables<V = LangVariable> {
|
export interface LangPairWithVariables<V = LangVariable> {
|
||||||
@ -2195,17 +2210,9 @@ export interface LangPairWithVariables<V = LangVariable> {
|
|||||||
'ProfileBirthdayValue': {
|
'ProfileBirthdayValue': {
|
||||||
'date': V;
|
'date': V;
|
||||||
};
|
};
|
||||||
'ProfileBirthdayValueYear': {
|
|
||||||
'date': V;
|
|
||||||
'age': V;
|
|
||||||
};
|
|
||||||
'ProfileBirthdayTodayValue': {
|
'ProfileBirthdayTodayValue': {
|
||||||
'date': V;
|
'date': V;
|
||||||
};
|
};
|
||||||
'ProfileBirthdayTodayValueYear': {
|
|
||||||
'date': V;
|
|
||||||
'age': V;
|
|
||||||
};
|
|
||||||
'ChannelEarnLearnCoinAbout': {
|
'ChannelEarnLearnCoinAbout': {
|
||||||
'link': V;
|
'link': V;
|
||||||
};
|
};
|
||||||
@ -3253,12 +3260,15 @@ export interface LangPairWithVariables<V = LangVariable> {
|
|||||||
'BotReadTextFromClipboardDescription': {
|
'BotReadTextFromClipboardDescription': {
|
||||||
'bot': V;
|
'bot': V;
|
||||||
};
|
};
|
||||||
|
'GroupStatusWithOnline': {
|
||||||
|
'status': V;
|
||||||
|
'onlineCount': V;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface LangPairPlural {
|
export interface LangPairPlural {
|
||||||
'DeleteForMeChatHint': undefined;
|
'DeleteForMeChatHint': undefined;
|
||||||
'DeleteForEveryoneHint': undefined;
|
'DeleteForEveryoneHint': undefined;
|
||||||
'PreviewDraggingAddItems': undefined;
|
|
||||||
'MediaReplaceInvalidError': undefined;
|
'MediaReplaceInvalidError': undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3428,6 +3438,14 @@ export interface LangPairPluralWithVariables<V = LangVariable> {
|
|||||||
'ShowMoreVoters': {
|
'ShowMoreVoters': {
|
||||||
'count': V;
|
'count': V;
|
||||||
};
|
};
|
||||||
|
'ProfileBirthdayValueAge': {
|
||||||
|
'date': V;
|
||||||
|
'age': V;
|
||||||
|
};
|
||||||
|
'ProfileBirthdayTodayValueAge': {
|
||||||
|
'date': V;
|
||||||
|
'age': V;
|
||||||
|
};
|
||||||
'GiftInfoDescription': {
|
'GiftInfoDescription': {
|
||||||
'amount': V;
|
'amount': V;
|
||||||
};
|
};
|
||||||
@ -3661,6 +3679,30 @@ export interface LangPairPluralWithVariables<V = LangVariable> {
|
|||||||
'GiftAuctionGifts': {
|
'GiftAuctionGifts': {
|
||||||
'count': V;
|
'count': V;
|
||||||
};
|
};
|
||||||
|
'AttachmentReplacePhoto': {
|
||||||
|
'count': V;
|
||||||
|
};
|
||||||
|
'AttachmentReplaceVideo': {
|
||||||
|
'count': V;
|
||||||
|
};
|
||||||
|
'AttachmentReplaceAudio': {
|
||||||
|
'count': V;
|
||||||
|
};
|
||||||
|
'AttachmentReplaceFile': {
|
||||||
|
'count': V;
|
||||||
|
};
|
||||||
|
'AttachmentSendPhoto': {
|
||||||
|
'count': V;
|
||||||
|
};
|
||||||
|
'AttachmentSendVideo': {
|
||||||
|
'count': V;
|
||||||
|
};
|
||||||
|
'AttachmentSendAudio': {
|
||||||
|
'count': V;
|
||||||
|
};
|
||||||
|
'AttachmentSendFile': {
|
||||||
|
'count': V;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
export type RegularLangKey = keyof LangPair;
|
export type RegularLangKey = keyof LangPair;
|
||||||
export type RegularLangKeyWithVariables = keyof LangPairWithVariables;
|
export type RegularLangKeyWithVariables = keyof LangPairWithVariables;
|
||||||
|
|||||||
@ -1,522 +0,0 @@
|
|||||||
/* eslint-disable @stylistic/max-len */
|
|
||||||
|
|
||||||
import type { ApiOldLangPack } from '../api/types';
|
|
||||||
|
|
||||||
export default {
|
|
||||||
Search: 'Search',
|
|
||||||
SavedMessages: 'Saved Messages',
|
|
||||||
ArchivedChats: 'Archived Chats',
|
|
||||||
Contacts: 'Contacts',
|
|
||||||
Settings: 'Settings',
|
|
||||||
lng_menu_night_mode: 'Night Mode',
|
|
||||||
lng_settings_enable_night_theme: 'Enable night mode',
|
|
||||||
'Appearance.Animations': 'ANIMATIONS',
|
|
||||||
TelegramFeatures: 'Telegram Features',
|
|
||||||
AccDescrOpenMenu2: 'Open menu',
|
|
||||||
NewMessageTitle: 'New Message',
|
|
||||||
NewChannel: 'New Channel',
|
|
||||||
NewGroup: 'New Group',
|
|
||||||
'Common.Close': 'Close',
|
|
||||||
FilterAllChats: 'All Chats',
|
|
||||||
MarkAsUnread: 'Mark as unread',
|
|
||||||
UnpinFromTop: 'Unpin from top',
|
|
||||||
'ChatList.Mute': 'Mute',
|
|
||||||
Archive: 'Archive',
|
|
||||||
Delete: 'Delete',
|
|
||||||
DeleteChat: 'Delete and exit',
|
|
||||||
FromYou: 'You',
|
|
||||||
formatDateSchedule: 'MMM d',
|
|
||||||
June: 'June',
|
|
||||||
'Month.GenJune': 'June',
|
|
||||||
'Month.ShortJune': 'Jun',
|
|
||||||
MarkAsRead: 'Mark as read',
|
|
||||||
PinToTop: 'Pin to top',
|
|
||||||
'ChatList.Unmute': 'Unmute',
|
|
||||||
'Group.LeaveGroup': 'Leave Group',
|
|
||||||
LeaveChannel: 'Leave Channel',
|
|
||||||
AttachPhoto: 'Photo',
|
|
||||||
UnreadMessages: 'Unread Messages',
|
|
||||||
'Weekday.Today': 'Today',
|
|
||||||
Message: 'Message',
|
|
||||||
AccDescrVoiceMessage: 'Record voice message',
|
|
||||||
AccDescrPageDown: 'Go to bottom',
|
|
||||||
chatDate: 'MMMM d',
|
|
||||||
January: 'January',
|
|
||||||
'Month.GenJanuary': 'January',
|
|
||||||
'Month.ShortJanuary': 'Jan',
|
|
||||||
February: 'February',
|
|
||||||
'Month.GenFebruary': 'February',
|
|
||||||
'Month.ShortFebruary': 'Feb',
|
|
||||||
March: 'March',
|
|
||||||
'Month.GenMarch': 'March',
|
|
||||||
'Month.ShortMarch': 'Mar',
|
|
||||||
April: 'April',
|
|
||||||
'Month.GenApril': 'April',
|
|
||||||
'Month.ShortApril': 'Apr',
|
|
||||||
May: 'May',
|
|
||||||
'Month.GenMay': 'May',
|
|
||||||
'Month.ShortMay': 'May',
|
|
||||||
'Weekday.Thursday': 'Thursday',
|
|
||||||
EditedMessage: 'edited',
|
|
||||||
chatFullDate: 'MMMM d, yyyy',
|
|
||||||
September: 'September',
|
|
||||||
'Month.GenSeptember': 'September',
|
|
||||||
'Month.ShortSeptember': 'Sep',
|
|
||||||
November: 'November',
|
|
||||||
'Month.GenNovember': 'November',
|
|
||||||
'Month.ShortNovember': 'Nov',
|
|
||||||
December: 'December',
|
|
||||||
'Month.GenDecember': 'December',
|
|
||||||
'Month.ShortDecember': 'Dec',
|
|
||||||
SearchAllChatsShort: 'Chats',
|
|
||||||
SharedMediaTab2: 'Media',
|
|
||||||
SharedLinksTab2: 'Links',
|
|
||||||
SharedFilesTab2: 'Files',
|
|
||||||
SharedMusicTab2: 'Music',
|
|
||||||
SharedVoiceTab2: 'Voice',
|
|
||||||
'PreviewSender.SendPhoto': {
|
|
||||||
oneValue: 'Send Photo',
|
|
||||||
otherValue: 'Send %d Photos',
|
|
||||||
},
|
|
||||||
Send: 'Send',
|
|
||||||
'Preview.Dragging.AddItems': {
|
|
||||||
oneValue: 'Add Item',
|
|
||||||
otherValue: 'Add Items',
|
|
||||||
},
|
|
||||||
Caption: 'Caption',
|
|
||||||
formatterMonthYear: 'MMMM yyyy',
|
|
||||||
'Weekday.ShortMonday': 'Mon',
|
|
||||||
'Weekday.ShortSaturday': 'Sat',
|
|
||||||
'Weekday.ShortFriday': 'Fri',
|
|
||||||
'Conversation.ScheduleMessage.SendOn': 'Send on %@ at %@',
|
|
||||||
'Weekday.ShortThursday': 'Thu',
|
|
||||||
'Weekday.ShortWednesday': 'Wed',
|
|
||||||
'Weekday.ShortTuesday': 'Tue',
|
|
||||||
'LastSeen.MinutesAgo': {
|
|
||||||
oneValue: 'last seen 1 minute ago',
|
|
||||||
otherValue: 'last seen %@ minutes ago',
|
|
||||||
},
|
|
||||||
'AttachmentMenu.PhotoOrVideo': 'Photo or Video',
|
|
||||||
AttachDocument: 'File',
|
|
||||||
SendWithoutSound: 'Send without sound',
|
|
||||||
ScheduleMessage: 'Schedule message',
|
|
||||||
'Chat.PanelUnpinAllMessages': 'Unpin All Messages',
|
|
||||||
'Chat.UnpinAllMessagesConfirmation': {
|
|
||||||
oneValue: 'Do you want to unpin %d message in this chat?',
|
|
||||||
otherValue: 'Do you want to unpin all %d messages in this chat?',
|
|
||||||
},
|
|
||||||
DialogUnpin: 'Unpin',
|
|
||||||
Cancel: 'Cancel',
|
|
||||||
AccDescrStickerSet: 'Sticker set',
|
|
||||||
Recent: 'Recent',
|
|
||||||
DeleteChatUser: 'Delete chat',
|
|
||||||
'ChatList.DeleteChatConfirmation': 'Are you sure you want to delete the chat\nwith %@?',
|
|
||||||
'ChatList.DeleteForEveryone': 'Delete for me and %@',
|
|
||||||
'ChatList.DeleteForCurrentUser': 'Delete just for me',
|
|
||||||
'LastSeen.HoursAgo': {
|
|
||||||
oneValue: 'last seen 1 hour ago',
|
|
||||||
otherValue: 'last seen %@ hours ago',
|
|
||||||
},
|
|
||||||
ForwardedMessage: 'Forwarded message',
|
|
||||||
'Weekday.Yesterday': 'Yesterday',
|
|
||||||
AttachVideo: 'Video',
|
|
||||||
Lately: 'last seen recently',
|
|
||||||
'Weekday.Tuesday': 'Tuesday',
|
|
||||||
'Weekday.Wednesday': 'Wednesday',
|
|
||||||
'Weekday.Friday': 'Friday',
|
|
||||||
'Weekday.Saturday': 'Saturday',
|
|
||||||
SearchFriends: 'Search contacts',
|
|
||||||
Online: 'online',
|
|
||||||
'LastSeen.JustNow': 'last seen just now',
|
|
||||||
AccDescrGoBack: 'Go back',
|
|
||||||
SETTINGS: 'Settings',
|
|
||||||
LogOutTitle: 'Log Out',
|
|
||||||
lng_settings_information: 'Edit profile',
|
|
||||||
Filters: 'Folders',
|
|
||||||
'Telegram.GeneralSettingsViewController': 'General Settings',
|
|
||||||
Notifications: 'Notifications',
|
|
||||||
DataSettings: 'Data and Storage',
|
|
||||||
PrivacySettings: 'Privacy and Security',
|
|
||||||
Language: 'Language',
|
|
||||||
FirstName: 'First name (required)',
|
|
||||||
PaymentCheckoutName: 'Name',
|
|
||||||
ChatSetPhotoOrVideo: 'Set Photo',
|
|
||||||
LastName: 'Last name (optional)',
|
|
||||||
UserBio: 'Bio',
|
|
||||||
lng_settings_about_bio: 'Any details such as age, occupation or city.\nExample: 23 y.o. designer from San Francisco',
|
|
||||||
Username: 'Username',
|
|
||||||
UsernameHelp: 'You can choose a username on **Telegram**. If you do, people will be able to find you by this username and contact you without needing your phone number.\n\nYou can use **a–z**, **0–9** and underscores. Minimum length is **5** characters.',
|
|
||||||
lng_username_link: 'This link opens a chat with you:',
|
|
||||||
lng_user_typing: 'typing...',
|
|
||||||
lng_send_action_record_video: 'recording video...',
|
|
||||||
lng_send_action_upload_video: 'uploading video...',
|
|
||||||
lng_send_action_record_audio: 'recording audio...',
|
|
||||||
lng_send_action_upload_audio: 'uploading audio...',
|
|
||||||
lng_send_action_upload_photo: 'uploading photo...',
|
|
||||||
lng_send_action_upload_file: 'uploading file...',
|
|
||||||
CropImage: 'Crop image',
|
|
||||||
Chats: {
|
|
||||||
oneValue: '%1$d chat',
|
|
||||||
otherValue: '%1$d chats',
|
|
||||||
},
|
|
||||||
FilterContacts: 'Contacts',
|
|
||||||
CreateNewFilterInfo: 'Create folders for different groups of chats and quickly switch between them.',
|
|
||||||
CreateNewFilter: 'Create New Folder',
|
|
||||||
FilterNew: 'New Folder',
|
|
||||||
FilterIncludeInfo: 'Choose chats and types of chats that will appear in this folder.',
|
|
||||||
FilterNameHint: 'Folder name',
|
|
||||||
FilterInclude: 'Included Chats',
|
|
||||||
FilterAddChats: 'Add Chats',
|
|
||||||
FilterExclude: 'Excluded Chats',
|
|
||||||
AutoDeleteConfirm: 'Confirm',
|
|
||||||
FilterChatTypes: 'Chat types',
|
|
||||||
FilterNonContacts: 'Non Contacts',
|
|
||||||
FilterGroups: 'Groups',
|
|
||||||
FilterChannels: 'Channels',
|
|
||||||
FilterBots: 'Bots',
|
|
||||||
FilterChats: 'Chats',
|
|
||||||
FilterColorTitle: 'Folder Color',
|
|
||||||
FilterColorHint: 'This color will be used for the folder\'s tag in the chat list',
|
|
||||||
ShowFolderTags: 'Show Folder Tags',
|
|
||||||
ShowFolderTagsHint: 'Display folder names for each chat in the chat list.',
|
|
||||||
TabsPosition: 'Tabs View',
|
|
||||||
TabsPositionLeft: 'Tabs on the left',
|
|
||||||
TabsPositionTop: 'Tabs at the top',
|
|
||||||
AccDescrChannel: 'Channel',
|
|
||||||
AccDescrGroup: 'Group',
|
|
||||||
Bot: 'bot',
|
|
||||||
BotChangeSettings: 'Change Bot Settings',
|
|
||||||
BotEditCommands: 'Edit Commands',
|
|
||||||
BotEditIntro: 'Edit Intro',
|
|
||||||
ServiceNotifications: 'Service notifications',
|
|
||||||
'LastSeen.TodayAt': 'last seen today at %@',
|
|
||||||
ALongTimeAgo: 'last seen a long time ago',
|
|
||||||
formatterYearMax: 'dd.MM.yyyy',
|
|
||||||
'LastSeen.AtDate': 'last seen %@',
|
|
||||||
'LastSeen.YesterdayAt': 'last seen yesterday at %@',
|
|
||||||
FilterMuted: 'Muted',
|
|
||||||
FilterArchived: 'Archived',
|
|
||||||
FilterRead: 'Read',
|
|
||||||
FilterEdit: 'Edit folder',
|
|
||||||
Members: {
|
|
||||||
oneValue: '%1$d member',
|
|
||||||
otherValue: '%1$d members',
|
|
||||||
},
|
|
||||||
General: 'General',
|
|
||||||
lng_settings_send_enter: 'Send with Enter',
|
|
||||||
lng_settings_send_cmdenter: 'Send with Cmd+Enter',
|
|
||||||
TextSize: 'Message Text Size',
|
|
||||||
ChatBackground: 'Chat Background',
|
|
||||||
'VoiceOver.Keyboard': 'Keyboard',
|
|
||||||
AutoDownloadMedia: 'Auto-Download Media',
|
|
||||||
AutodownloadPrivateChats: 'Private Chats',
|
|
||||||
AutodownloadGroupChats: 'Group Chats',
|
|
||||||
AutoplayMedia: 'Auto-play media',
|
|
||||||
GifsTab2: 'GIFs',
|
|
||||||
'DataAndStorage.Autoplay.Videos': 'Videos',
|
|
||||||
AccDescrStickers: 'Stickers',
|
|
||||||
SuggestStickers: 'Suggest stickers by emoji',
|
|
||||||
LoopAnimatedStickers: 'Loop Animated Stickers',
|
|
||||||
'StickerPack.StickerCount': {
|
|
||||||
oneValue: '1 sticker',
|
|
||||||
otherValue: '%@ stickers',
|
|
||||||
},
|
|
||||||
UploadImage: 'Upload image',
|
|
||||||
SetColor: 'Set a color',
|
|
||||||
ThemeResetToDefaults: 'Reset to default',
|
|
||||||
BackgroundBlurred: 'Blurred',
|
|
||||||
NotificationsForPrivateChats: 'Notifications for private chats',
|
|
||||||
'UserInfo.NotificationsEnabled': 'Enabled',
|
|
||||||
MessagePreview: 'Message Preview',
|
|
||||||
NotificationsForGroups: 'Notifications for groups',
|
|
||||||
NotificationsForChannels: 'Notifications for channels',
|
|
||||||
PhoneOther: 'Other',
|
|
||||||
ContactJoined: 'Contact joined Telegram',
|
|
||||||
'UserInfo.NotificationsDisabled': 'Disabled',
|
|
||||||
BlockedUsers: 'Blocked Users',
|
|
||||||
TwoStepVerification: 'Two-Step Verification',
|
|
||||||
PasswordOff: 'Off',
|
|
||||||
SessionsTitle: 'Active Sessions',
|
|
||||||
PrivacyTitle: 'Privacy',
|
|
||||||
PrivacyPhoneTitle: 'Who can see my phone number?',
|
|
||||||
LastSeenTitle: 'Who can see your Last Seen time?',
|
|
||||||
PrivacyProfilePhotoTitle: 'Who can see my profile photos & videos?',
|
|
||||||
PrivacyForwardsTitle: 'Who can add a link to my account when forwarding my messages?',
|
|
||||||
WhoCanAddMe: 'Who can add me to group chats?',
|
|
||||||
lng_settings_sensitive_title: 'Sensitive content',
|
|
||||||
lng_settings_sensitive_disable_filtering: 'Disable filtering',
|
|
||||||
lng_settings_sensitive_about: 'Display sensitive media in public channels on all your Telegram devices.',
|
|
||||||
P2PContacts: 'My Contacts',
|
|
||||||
P2PEverybody: 'Everybody',
|
|
||||||
P2PNobody: 'Nobody',
|
|
||||||
Users: {
|
|
||||||
oneValue: '%1$d user',
|
|
||||||
otherValue: '%1$d users',
|
|
||||||
},
|
|
||||||
BlockedUsersInfo: 'Blocked users will not be able to contact you and will not see your Last Seen time.',
|
|
||||||
EnabledPasswordText: 'You have enabled Two-Step verification.\nYou\'ll need the password you set up here to log in to your Telegram account.',
|
|
||||||
ChangePassword: 'Change Password',
|
|
||||||
TurnPasswordOff: 'Turn Password Off',
|
|
||||||
SetRecoveryEmail: 'Set Recovery Email',
|
|
||||||
PleaseEnterCurrentPassword: 'Enter your password',
|
|
||||||
Next: 'Next',
|
|
||||||
'AuthSessions.CurrentSession': 'CURRENT SESSION',
|
|
||||||
TerminateAllSessions: 'Terminate All Other Sessions',
|
|
||||||
PrivacyPhone: 'Phone Number',
|
|
||||||
PrivacyExceptions: 'Exceptions',
|
|
||||||
AlwaysShareWith: 'Always Share With',
|
|
||||||
EditAdminAddUsers: 'Add Users',
|
|
||||||
NeverShareWith: 'Never Share With',
|
|
||||||
AlwaysShareWithPlaceholder: 'Always share with users...',
|
|
||||||
AlwaysShareWithTitle: 'Always Share',
|
|
||||||
NeverShareWithPlaceholder: 'Never share with users...',
|
|
||||||
NeverShareWithTitle: 'Never Share',
|
|
||||||
'Privacy.ProfilePhoto': 'Profile Photo',
|
|
||||||
FilterNoChatsToDisplay: 'Folder is empty',
|
|
||||||
AttachSticker: 'Sticker',
|
|
||||||
'ChatList.Search.ShowMore': 'Show more',
|
|
||||||
'DialogList.SearchSectionDialogs': 'Chats and Contacts',
|
|
||||||
SearchMessages: 'Messages',
|
|
||||||
'Weekday.ShortSunday': 'Sun',
|
|
||||||
'DialogList.SearchSectionGlobal': 'Global Search',
|
|
||||||
Subscribers: {
|
|
||||||
oneValue: '%1$d subscriber',
|
|
||||||
otherValue: '%1$d subscribers',
|
|
||||||
},
|
|
||||||
ChannelLeaveAlertWithName: 'Are you sure you want to leave **%1$s**?',
|
|
||||||
'ChatList.Search.ShowLess': 'Show less',
|
|
||||||
ChannelDelete: 'Delete Channel',
|
|
||||||
'ChatList.DeleteAndLeaveGroupConfirmation': 'Are you sure you want to leave and delete %@?',
|
|
||||||
'Chat.Input.Delete': 'Delete and Leave',
|
|
||||||
formatDateScheduleYear: 'MMM d yyyy',
|
|
||||||
October: 'October',
|
|
||||||
'Month.GenOctober': 'October',
|
|
||||||
'Month.ShortOctober': 'Oct',
|
|
||||||
August: 'August',
|
|
||||||
'Month.GenAugust': 'August',
|
|
||||||
'Month.ShortAugust': 'Aug',
|
|
||||||
July: 'July',
|
|
||||||
'Month.GenJuly': 'July',
|
|
||||||
'Month.ShortJuly': 'Jul',
|
|
||||||
'ChatList.Search.NoResults': 'No Results',
|
|
||||||
'ChatList.Search.NoResultsDescription': 'There were no results.\nTry a new search.',
|
|
||||||
lng_in_dlg_album: 'Album',
|
|
||||||
ReportSelectMessages: 'Select messages',
|
|
||||||
'VoiceOver.Chat.MessagesSelected': {
|
|
||||||
oneValue: '%@ message selected',
|
|
||||||
otherValue: '%@ messages selected',
|
|
||||||
},
|
|
||||||
'Conversation.DeleteManyMessages': 'Delete Messages',
|
|
||||||
AreYouSureDeleteFewMessages: 'Are you sure you want to delete these messages?',
|
|
||||||
Reply: 'Reply',
|
|
||||||
Copy: 'Copy',
|
|
||||||
DialogPin: 'Pin',
|
|
||||||
Forward: 'Forward',
|
|
||||||
'Common.Select': 'Select',
|
|
||||||
DeleteSingleMessagesTitle: 'Delete message',
|
|
||||||
AreYouSureDeleteSingleMessage: 'Are you sure you want to delete this message?',
|
|
||||||
PinMessageAlertTitle: 'Pin message',
|
|
||||||
PinMessageAlertChat: 'Do you want to pin this message at the top of the chat?',
|
|
||||||
Close: 'Close',
|
|
||||||
ForwardTo: 'Forward to...',
|
|
||||||
SavedMessagesInfo: 'Forward here to save.',
|
|
||||||
SendMessage: 'Send Message',
|
|
||||||
Poll: 'Poll',
|
|
||||||
GroupMembers: 'Members',
|
|
||||||
Info: 'Info',
|
|
||||||
EditAdminGroupDeleteMessages: 'Delete Messages',
|
|
||||||
Edit: 'Edit',
|
|
||||||
'Common.Back': 'Back',
|
|
||||||
SharedMedia: 'Shared Media',
|
|
||||||
lng_dlg_search_for_messages: 'Search for messages',
|
|
||||||
JumpToDate: 'Jump to Date',
|
|
||||||
lng_search_no_results: 'No messages found',
|
|
||||||
'StickerPack.RemoveStickerCount': {
|
|
||||||
oneValue: 'Remove 1 Sticker',
|
|
||||||
otherValue: 'Remove %@ Stickers',
|
|
||||||
},
|
|
||||||
AccActionDownload: 'Download',
|
|
||||||
AccActionPlay: 'Play',
|
|
||||||
ZoomOut: 'Zoom out',
|
|
||||||
AccDescrPrevious: 'Previous',
|
|
||||||
'TextFormat.AddLinkTitle': 'Add Link',
|
|
||||||
Save: 'Save',
|
|
||||||
Updating: 'Updating...',
|
|
||||||
lng_context_forward_msg: 'Forward Message',
|
|
||||||
Comments: {
|
|
||||||
oneValue: '%1$d Comment',
|
|
||||||
otherValue: '%1$d Comments',
|
|
||||||
},
|
|
||||||
ChannelSubscribers: 'Subscribers',
|
|
||||||
LeaveAComment: 'Leave a comment',
|
|
||||||
ChatsMute: 'Mute',
|
|
||||||
'GroupInfo.DeleteAndExit': 'Delete and Exit',
|
|
||||||
ChatsUnmute: 'Unmute',
|
|
||||||
'Conversation.DeleteMessagesForEveryone': 'Delete for everyone',
|
|
||||||
lng_mediaview_profile_photo: 'Profile Photo',
|
|
||||||
lng_media_file_empty_search: 'No files found',
|
|
||||||
lng_media_song_empty_search: 'No music files found',
|
|
||||||
EnterChannelName: 'Channel name',
|
|
||||||
DescriptionPlaceholder: 'Description',
|
|
||||||
ChannelType: 'Channel Type',
|
|
||||||
TypePublic: 'Public',
|
|
||||||
Discussion: 'Discussion',
|
|
||||||
DiscussionUnlink: 'Unlink',
|
|
||||||
ChannelAdministrators: 'Administrators',
|
|
||||||
ChannelSignMessages: 'Sign Messages',
|
|
||||||
ChannelDeleteAlert: 'Wait! Deleting this channel will remove all subscribers and all messages will be lost. Delete the channel anyway?',
|
|
||||||
ChannelTypeHeader: 'Channel type',
|
|
||||||
ChannelPrivate: 'Private Channel',
|
|
||||||
ChannelPrivateInfo: 'Private channels can only be joined via an invite link.',
|
|
||||||
ChannelPublic: 'Public Channel',
|
|
||||||
ChannelPublicInfo: 'Public channels can be found in search, anyone can join them.',
|
|
||||||
'Channel.Username.CreatePublicLinkHelp': 'People can share this link with others and find your channel using Telegram search.',
|
|
||||||
SetUrlPlaceholder: 'Link',
|
|
||||||
ChannelPrivateLinkHelp: 'People can join your channel by following this link. You can revoke the link any time.',
|
|
||||||
RevokeLink: 'Revoke Link',
|
|
||||||
RevokeAlert: 'Are you sure you want to revoke this link? Once the link is revoked, no one will be able to join using it.',
|
|
||||||
RevokeButton: 'Revoke',
|
|
||||||
DiscussionUnlinkGroup: 'Unlink Group',
|
|
||||||
DiscussionUnlinkChannelAlert: 'Are you sure you want to unlink **%1$s** from this channel?',
|
|
||||||
EventLog: 'Recent Actions',
|
|
||||||
EventLogInfoDetailChannel: 'This is a list of all service actions taken by the channel\'s admins in the last 48 hours.',
|
|
||||||
ChannelCreator: 'Owner',
|
|
||||||
EditAdminRights: 'Edit admin rights',
|
|
||||||
EditAdminWhatCanDo: 'What can this admin do?',
|
|
||||||
EditAdminChangeChannelInfo: 'Change Channel Info',
|
|
||||||
EditAdminPostMessages: 'Post Messages',
|
|
||||||
EditAdminEditMessages: 'Edit Messages of Others',
|
|
||||||
EditAdminDeleteMessages: 'Delete Messages of Others',
|
|
||||||
EditAdminAddAdmins: 'Add New Admins',
|
|
||||||
'Group.Info.AdminLog': 'Recent Actions',
|
|
||||||
EventLogAllEvents: 'All actions',
|
|
||||||
EventLogFilterNewAdmins: 'Admin rights',
|
|
||||||
EventLogFilterNewMembers: 'New members',
|
|
||||||
EventLogFilterChannelInfo: 'Channel info',
|
|
||||||
EventLogFilterDeletedMessages: 'Deleted messages',
|
|
||||||
EventLogFilterEditedMessages: 'Edited messages',
|
|
||||||
EventLogFilterLeavingMembers: 'Leaving members',
|
|
||||||
'Channel.Management.Title': 'Admins',
|
|
||||||
EventLogAllAdmins: 'All admins',
|
|
||||||
WithinAWeek: 'last seen within a week',
|
|
||||||
WithinAMonth: 'last seen within a month',
|
|
||||||
EventLogFilterPinnedMessages: 'Pinned messages',
|
|
||||||
UnpinMessageAlertTitle: 'Unpin message',
|
|
||||||
PinnedMessage: 'Pinned Message',
|
|
||||||
OnlineCount: {
|
|
||||||
oneValue: '%1$d online',
|
|
||||||
otherValue: '%1$d online',
|
|
||||||
},
|
|
||||||
GroupName: 'Group name',
|
|
||||||
GroupType: 'Group Type',
|
|
||||||
LinkedChannel: 'Linked Channel',
|
|
||||||
ChannelPermissions: 'Permissions',
|
|
||||||
ChatHistory: 'Chat history for new members',
|
|
||||||
DeleteMega: 'Delete Group',
|
|
||||||
AreYouSureDeleteThisChatWithGroup: 'Are you sure you want to delete the chat **%1$s**?',
|
|
||||||
DeleteGroupForAll: 'Delete the group for all members',
|
|
||||||
GroupTypeHeader: 'Group type',
|
|
||||||
MegaPrivate: 'Private Group',
|
|
||||||
MegaPrivateInfo: 'Private groups can only be joined if you were invited or have an invite link.',
|
|
||||||
MegaPublic: 'Public Group',
|
|
||||||
MegaPublicInfo: 'Public groups can be found in search, chat history is available to everyone and anyone can join.',
|
|
||||||
'Group.Username.CreatePublicLinkHelp': 'People can share this link with others and find your group using Telegram search.',
|
|
||||||
MegaPrivateLinkHelp: 'People can join your group by following this link. You can revoke the link any time.',
|
|
||||||
DiscussionUnlinkChannel: 'Unlink Channel',
|
|
||||||
DiscussionUnlinkGroupAlert: 'Are you sure you want to unlink **%1$s** from this group?',
|
|
||||||
ChannelPermissionsHeader: 'What can members of this group do?',
|
|
||||||
UserRestrictionsSend: 'Send Messages',
|
|
||||||
UserRestrictionsSendMedia: 'Send Media',
|
|
||||||
UserRestrictionsSendStickers: 'Send Stickers and GIFs',
|
|
||||||
UserRestrictionsSendPolls: 'Send Polls',
|
|
||||||
UserRestrictionsEmbedLinks: 'Embed Links',
|
|
||||||
UserRestrictionsInviteUsers: 'Add Users',
|
|
||||||
UserRestrictionsPinMessages: 'Pin Messages',
|
|
||||||
UserRestrictionsChangeInfo: 'Change Chat Info',
|
|
||||||
ChannelBlockedUsers: 'Removed users',
|
|
||||||
ChannelAddException: 'Add Exception',
|
|
||||||
NoBlockedGroup2: 'Users removed from the group by the admins can\'t rejoin via invite links.',
|
|
||||||
EventLogInfoDetail: 'This is a list of notable actions by members and admins in the last 48 hours.',
|
|
||||||
EditAdminChangeGroupInfo: 'Change Group Info',
|
|
||||||
EditAdminBanUsers: 'Ban Users',
|
|
||||||
EditAdminPinMessages: 'Pin Messages',
|
|
||||||
EditAdminSendAnonymously: 'Remain Anonymous',
|
|
||||||
EditAdminRank: 'Custom title',
|
|
||||||
RecentStickers: 'Recently Used',
|
|
||||||
Emoji1: 'Smileys and people',
|
|
||||||
Emoji2: 'Animals and nature',
|
|
||||||
Emoji3: 'Food and drink',
|
|
||||||
Emoji4: 'Activity',
|
|
||||||
Emoji5: 'Travel and places',
|
|
||||||
Emoji6: 'Objects',
|
|
||||||
Emoji7: 'Symbols',
|
|
||||||
Emoji8: 'Flags',
|
|
||||||
FavoriteStickers: 'Favorites',
|
|
||||||
SearchStickersHint: 'Search sticker sets',
|
|
||||||
Stickers: {
|
|
||||||
oneValue: '%1$d sticker',
|
|
||||||
otherValue: '%1$d stickers',
|
|
||||||
},
|
|
||||||
'Stickers.Install': 'ADD',
|
|
||||||
'StickerPack.AddStickerCount': {
|
|
||||||
oneValue: 'Add 1 Sticker',
|
|
||||||
otherValue: 'Add %@ Stickers',
|
|
||||||
},
|
|
||||||
SearchGifsTitle: 'Search GIFs',
|
|
||||||
'PreviewSender.SendFile': {
|
|
||||||
oneValue: 'Send File',
|
|
||||||
otherValue: 'Send %d Files',
|
|
||||||
},
|
|
||||||
Phone: 'Phone',
|
|
||||||
Reminders: 'Reminders',
|
|
||||||
MessageScheduledOn: 'Scheduled for %1$s',
|
|
||||||
NewPoll: 'New Poll',
|
|
||||||
Create: 'Create',
|
|
||||||
AskAQuestion: 'Ask a Question',
|
|
||||||
PollOptions: 'Poll options',
|
|
||||||
'CreatePoll.AddOption': 'Add an Option',
|
|
||||||
PollAnonymous: 'Anonymous Voting',
|
|
||||||
PollMultiple: 'Multiple Answers',
|
|
||||||
PollQuiz: 'Quiz Mode',
|
|
||||||
PaymentReceipt: 'Receipt',
|
|
||||||
NoMessages: 'No messages here yet...',
|
|
||||||
PinnedMessagesCount: {
|
|
||||||
oneValue: 'Pinned Message',
|
|
||||||
otherValue: '%1$d Pinned Messages',
|
|
||||||
},
|
|
||||||
'Chat.Pinned.UnpinAll': {
|
|
||||||
oneValue: 'Unpin %d Message',
|
|
||||||
otherValue: 'Unpin All %d Messages',
|
|
||||||
},
|
|
||||||
CommentsCount: {
|
|
||||||
oneValue: '%1$d comment',
|
|
||||||
otherValue: '%1$d comments',
|
|
||||||
},
|
|
||||||
'Conversation.DefaultRestrictedMedia': 'Posting media content isn\'t allowed in this group.',
|
|
||||||
DiscussionStarted: 'Discussion started',
|
|
||||||
DiscussChannel: 'channel',
|
|
||||||
'SharedMedia.EmptyTitle': 'No media files yet',
|
|
||||||
QuizPoll: 'Quiz',
|
|
||||||
PollViewResults: 'VIEW RESULTS',
|
|
||||||
'Chat.Quiz.TotalVotesEmpty': 'No answers yet',
|
|
||||||
lng_update_telegram: 'Update Telegram',
|
|
||||||
AutoDownloadPhotosTitle: 'Auto-download photos',
|
|
||||||
AutoDownloadVideosTitle: 'Auto-download videos and GIFs',
|
|
||||||
AutoDownloadFilesTitle: 'Auto-download files and music',
|
|
||||||
'ChannelVisibility.Forwarding.ChannelTitle': 'Forwarding From This Channel',
|
|
||||||
'ChannelVisibility.Forwarding.GroupTitle': 'Forwarding From This Group',
|
|
||||||
'ChannelVisibility.Forwarding.ChannelInfo': 'Subscribers can forward messages from this channel and save media files.',
|
|
||||||
'ChannelVisibility.Forwarding.GroupInfo': 'Members can forward messages from this group and save media files.',
|
|
||||||
'ChannelVisibility.Forwarding.Enabled': 'Allow Forwarding',
|
|
||||||
'ChannelVisibility.Forwarding.Disabled': 'Restrict Forwarding',
|
|
||||||
'Settings.TipsUsername': 'TelegramTips',
|
|
||||||
FoldersAllChatsDesc: 'All unarchived chats',
|
|
||||||
'Conversation.ErrorInaccessibleMessage': 'Unfortunately, you can\'t access this message. You aren\'t a member of the chat where it was posted.',
|
|
||||||
'Video.Unsupported.Desktop': 'Unfortunately, this video can\'t be played on Telegram Web. Try opening it with our **desktop 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',
|
|
||||||
OpenMapWith: 'Open map with...',
|
|
||||||
FullDateTimeFormat: '%@, %@',
|
|
||||||
ProfileOpenAppTerms: 'Terms of Service for Mini Apps',
|
|
||||||
ProfileBotOpenAppInfoLink: 'https://telegram.org/tos/mini-apps',
|
|
||||||
} as ApiOldLangPack;
|
|
||||||
@ -105,7 +105,6 @@ const PLURAL_RULES = {
|
|||||||
const cache = new Map<string, string>();
|
const cache = new Map<string, string>();
|
||||||
|
|
||||||
let langPack: ApiOldLangPack | undefined;
|
let langPack: ApiOldLangPack | undefined;
|
||||||
let fallbackLangPack: ApiOldLangPack | undefined;
|
|
||||||
|
|
||||||
const {
|
const {
|
||||||
addCallback,
|
addCallback,
|
||||||
@ -128,11 +127,7 @@ function createLangFn() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!fallbackLangPack) {
|
const langString = langPack?.[key];
|
||||||
void importFallbackLangPack();
|
|
||||||
}
|
|
||||||
|
|
||||||
const langString = langPack?.[key] || fallbackLangPack?.[key];
|
|
||||||
if (!langString) {
|
if (!langString) {
|
||||||
return key;
|
return key;
|
||||||
}
|
}
|
||||||
@ -157,7 +152,7 @@ export function getTranslationFn(): LangFn {
|
|||||||
/**
|
/**
|
||||||
* @deprecated Migrate to `changeLanguage` in `util/localization.ts` instead
|
* @deprecated Migrate to `changeLanguage` in `util/localization.ts` instead
|
||||||
*/
|
*/
|
||||||
export async function oldSetLanguage(langCode: LangCode, callback?: NoneToVoidFunction, withFallback = false) {
|
export async function oldSetLanguage(langCode: LangCode, callback?: NoneToVoidFunction) {
|
||||||
loadAndChangeLanguage(langCode, true);
|
loadAndChangeLanguage(langCode, true);
|
||||||
if (langPack && langCode === currentLangCode) {
|
if (langPack && langCode === currentLangCode) {
|
||||||
if (callback) {
|
if (callback) {
|
||||||
@ -169,10 +164,6 @@ export async function oldSetLanguage(langCode: LangCode, callback?: NoneToVoidFu
|
|||||||
|
|
||||||
let newLangPack = await cacheApi.fetch(LANG_CACHE_NAME, langCode, cacheApi.Type.Json);
|
let newLangPack = await cacheApi.fetch(LANG_CACHE_NAME, langCode, cacheApi.Type.Json);
|
||||||
if (!newLangPack) {
|
if (!newLangPack) {
|
||||||
if (withFallback) {
|
|
||||||
await importFallbackLangPack();
|
|
||||||
}
|
|
||||||
|
|
||||||
newLangPack = await fetchRemote(langCode);
|
newLangPack = await fetchRemote(langCode);
|
||||||
if (!newLangPack) {
|
if (!newLangPack) {
|
||||||
return;
|
return;
|
||||||
@ -212,15 +203,6 @@ export function setTimeFormat(timeFormat: TimeFormat) {
|
|||||||
runCallbacks();
|
runCallbacks();
|
||||||
}
|
}
|
||||||
|
|
||||||
async function importFallbackLangPack() {
|
|
||||||
if (fallbackLangPack) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
fallbackLangPack = (await import('./fallbackLangPack')).default;
|
|
||||||
runCallbacks();
|
|
||||||
}
|
|
||||||
|
|
||||||
async function fetchRemote(langCode: string): Promise<ApiOldLangPack | undefined> {
|
async function fetchRemote(langCode: string): Promise<ApiOldLangPack | undefined> {
|
||||||
const remote = await callApi('oldFetchLangPack', { sourceLangPacks: LANG_PACKS, langCode });
|
const remote = await callApi('oldFetchLangPack', { sourceLangPacks: LANG_PACKS, langCode });
|
||||||
if (remote) {
|
if (remote) {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user