UI: Fix RTL styles after reload on some components (#6442)

This commit is contained in:
zubiden 2025-11-06 11:36:53 +01:00 committed by Alexander Zinchuk
parent f426014dbc
commit d2b8617133
49 changed files with 169 additions and 149 deletions

View File

@ -2314,4 +2314,4 @@
"UserNoteTitle" = "Notes";
"UserNoteHint" = "only visible to you";
"EditUserNoteHint" = "Notes are only visible to you.";
"AriaStoryTogglerOpen" = "Open Story List";

View File

@ -11,6 +11,7 @@ import type {
import type { BufferedRange } from '../../hooks/useBuffering';
import type { OldLangFn } from '../../hooks/useOldLang';
import type { ThemeKey } from '../../types';
import type { LangFn } from '../../util/localization';
import { ApiMediaFormat } from '../../api/types';
import { AudioOrigin } from '../../types';
@ -38,6 +39,7 @@ import { MAX_EMPTY_WAVEFORM_POINTS, renderWaveform } from './helpers/waveform';
import useAppLayout from '../../hooks/useAppLayout';
import useAudioPlayer from '../../hooks/useAudioPlayer';
import useBuffering from '../../hooks/useBuffering';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useMedia from '../../hooks/useMedia';
import useMediaWithLoadProgress from '../../hooks/useMediaWithLoadProgress';
@ -133,8 +135,8 @@ const Audio = ({
const isVoice = Boolean(voice || video);
const isSeeking = useRef<boolean>(false);
const seekerRef = useRef<HTMLDivElement>();
const lang = useOldLang();
const { isRtl } = lang;
const oldLang = useOldLang();
const lang = useLang();
const { isMobile } = useAppLayout();
const [isActivated, setIsActivated] = useState(false);
@ -314,7 +316,7 @@ const Audio = ({
function renderSecondLine() {
if (isVoice) {
return (
<div className="meta" dir={isRtl ? 'rtl' : undefined}>
<div className="meta" dir={lang.isRtl ? 'rtl' : undefined}>
{formatMediaDuration((voice || video)!.duration)}
</div>
);
@ -323,7 +325,7 @@ const Audio = ({
const { performer } = audio!;
return (
<div className="meta" dir={isRtl ? 'rtl' : undefined}>
<div className="meta" dir={lang.isRtl ? 'rtl' : undefined}>
{formatMediaDuration(duration)}
<span className="bullet">&bull;</span>
{performer && <span className="performer" title={performer}>{renderText(performer)}</span>}
@ -364,14 +366,14 @@ const Audio = ({
className="date"
onClick={handleDateClick}
>
{formatPastTimeShort(lang, date * 1000)}
{formatPastTimeShort(oldLang, date * 1000)}
</Link>
)}
</div>
</div>
{withSeekline && (
<div className="meta search-result" dir={isRtl ? 'rtl' : undefined}>
<div className="meta search-result" dir={lang.isRtl ? 'rtl' : undefined}>
<span className="duration with-seekline" dir="auto">
{playProgress < 1 && formatMediaDuration(duration * playProgress, duration)}
</span>
@ -462,6 +464,7 @@ const Audio = ({
{origin === AudioOrigin.Search && renderWithTitle()}
{origin !== AudioOrigin.Search && audio && renderAudio(
lang,
oldLang,
audio,
duration,
isPlaying,
@ -506,7 +509,8 @@ function getSeeklineSpikeAmounts(isMobile?: boolean, withAvatar?: boolean) {
}
function renderAudio(
lang: OldLangFn,
lang: LangFn,
oldLang: OldLangFn,
audio: ApiAudio,
duration: number,
isPlaying: boolean,
@ -554,7 +558,7 @@ function renderAudio(
<>
<span className="bullet">&bull;</span>
<Link className="date" onClick={handleDateClick}>
{formatMediaDateTime(lang, date * 1000, true)}
{formatMediaDateTime(oldLang, date * 1000, true)}
</Link>
</>
)}

View File

@ -6,7 +6,7 @@ import type { AvatarSize } from './Avatar';
import buildClassName from '../../util/buildClassName';
import useOldLang from '../../hooks/useOldLang';
import useLang from '../../hooks/useLang';
import Avatar, { AVATAR_SIZES } from './Avatar';
@ -29,7 +29,7 @@ const AvatarList: FC<OwnProps> = ({
limit = DEFAULT_LIMIT,
badgeText,
}) => {
const lang = useOldLang();
const lang = useLang();
const pxSize = typeof size === 'number' ? size : AVATAR_SIZES[size];

View File

@ -18,7 +18,7 @@ import renderText from './helpers/renderText';
import { getIsMobile } from '../../hooks/useAppLayout';
import { useFastClick } from '../../hooks/useFastClick';
import useOldLang from '../../hooks/useOldLang';
import useLang from '../../hooks/useLang';
import TopicIcon from './TopicIcon';
@ -47,7 +47,7 @@ const ChatForumLastMessage = ({
const lastMessageRef = useRef<HTMLDivElement>();
const mainColumnRef = useRef<HTMLDivElement>();
const lang = useOldLang();
const lang = useLang();
const [lastActiveTopic, ...otherTopics] = useMemo(() => {
if (!topics) {

View File

@ -17,6 +17,7 @@ import { selectIsChatWithSelf, selectUser } from '../../global/selectors';
import { isUserId } from '../../util/entities/ids';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
@ -72,7 +73,8 @@ const DeleteChatModal: FC<OwnProps & StateProps> = ({
deleteChat,
} = getActions();
const lang = useOldLang();
const oldLang = useOldLang();
const lang = useLang();
const chatTitle = getChatTitle(lang, chat);
const handleDeleteForAll = useLastCallback(() => {
@ -129,7 +131,7 @@ const DeleteChatModal: FC<OwnProps & StateProps> = ({
peer={chat}
isSavedMessages={isChatWithSelf}
/>
<h3 className="modal-title">{lang(renderTitle())}</h3>
<h3 className="modal-title">{oldLang(renderTitle())}</h3>
</div>
);
}
@ -159,7 +161,7 @@ const DeleteChatModal: FC<OwnProps & StateProps> = ({
return (
<p>
{renderText(
isChatWithSelf ? lang('ClearHistoryMyNotesMessage') : lang('ClearHistoryMessageSingle', chatTitle),
isChatWithSelf ? oldLang('ClearHistoryMyNotesMessage') : oldLang('ClearHistoryMessageSingle', chatTitle),
['simple_markdown', 'emoji'],
)}
</p>
@ -168,16 +170,16 @@ const DeleteChatModal: FC<OwnProps & StateProps> = ({
if (isChannel && chat.isCreator) {
return (
<p>
{renderText(lang('ChatList.DeleteAndLeaveGroupConfirmation', chatTitle), ['simple_markdown', 'emoji'])}
{renderText(oldLang('ChatList.DeleteAndLeaveGroupConfirmation', chatTitle), ['simple_markdown', 'emoji'])}
</p>
);
}
if ((isChannel && !chat.isCreator) || isBasicGroup || isSuperGroup) {
return <p>{renderText(lang('ChannelLeaveAlertWithName', chatTitle), ['simple_markdown', 'emoji'])}</p>;
return <p>{renderText(oldLang('ChannelLeaveAlertWithName', chatTitle), ['simple_markdown', 'emoji'])}</p>;
}
return <p>{renderText(lang('ChatList.DeleteChatConfirmation', contactName), ['simple_markdown', 'emoji'])}</p>;
return <p>{renderText(oldLang('ChatList.DeleteChatConfirmation', contactName), ['simple_markdown', 'emoji'])}</p>;
}
function renderActionText() {
@ -211,17 +213,17 @@ const DeleteChatModal: FC<OwnProps & StateProps> = ({
<div className="dialog-buttons-column">
{isBot && !isSavedDialog && (
<Button color="danger" className="confirm-dialog-button" isText onClick={handleDeleteAndStop}>
{lang('DeleteAndStop')}
{oldLang('DeleteAndStop')}
</Button>
)}
{canDeleteForAll && (
<Button color="danger" className="confirm-dialog-button" isText onClick={handleDeleteForAll}>
{contactName ? renderText(lang('ChatList.DeleteForEveryone', contactName)) : lang('DeleteForAll')}
{contactName ? renderText(oldLang('ChatList.DeleteForEveryone', contactName)) : oldLang('DeleteForAll')}
</Button>
)}
{!isPrivateChat && chat.isCreator && !isSavedDialog && (
<Button color="danger" className="confirm-dialog-button" isText onClick={handleDeleteChat}>
{lang('DeleteForAll')}
{oldLang('DeleteForAll')}
</Button>
)}
<Button
@ -230,9 +232,9 @@ const DeleteChatModal: FC<OwnProps & StateProps> = ({
isText
onClick={(isPrivateChat || isSavedDialog) ? handleDeleteChat : handleLeaveChat}
>
{lang(renderActionText())}
{oldLang(renderActionText())}
</Button>
<Button className="confirm-dialog-button" isText onClick={onClose}>{lang('Cancel')}</Button>
<Button className="confirm-dialog-button" isText onClick={onClose}>{oldLang('Cancel')}</Button>
</div>
</Modal>
);

View File

@ -357,7 +357,7 @@ const DeleteMessageModal: FC<OwnProps & StateProps> = ({
return (
<div
className={shouldShowOption && styles.container}
dir={oldLang.isRtl ? 'rtl' : undefined}
dir={lang.isRtl ? 'rtl' : undefined}
>
{shouldShowOption && (
<AvatarList

View File

@ -1,9 +1,9 @@
import type { FC } from '../../lib/teact/teact';
import { memo } from '@teact';
import buildClassName from '../../util/buildClassName';
import renderText from './helpers/renderText';
import useOldLang from '../../hooks/useOldLang';
import useLang from '../../hooks/useLang';
import './DotAnimation.scss';
@ -12,8 +12,8 @@ type OwnProps = {
className?: string;
};
const DotAnimation: FC<OwnProps> = ({ content, className }) => {
const lang = useOldLang();
const DotAnimation = ({ content, className }: OwnProps) => {
const lang = useLang();
return (
<span className={buildClassName('DotAnimation', className)} dir={lang.isRtl ? 'rtl' : 'auto'}>
{renderText(content)}
@ -22,4 +22,4 @@ const DotAnimation: FC<OwnProps> = ({ content, className }) => {
);
};
export default DotAnimation;
export default memo(DotAnimation);

View File

@ -1,5 +1,4 @@
import type { ElementRef, FC } from '../../lib/teact/teact';
import type React from '../../lib/teact/teact';
import {
memo, useMemo, useRef, useState,
} from '../../lib/teact/teact';
@ -15,6 +14,7 @@ import renderText from './helpers/renderText';
import useAppLayout from '../../hooks/useAppLayout';
import useCanvasBlur from '../../hooks/useCanvasBlur';
import useLang from '../../hooks/useLang';
import useMediaTransitionDeprecated from '../../hooks/useMediaTransitionDeprecated';
import useOldLang from '../../hooks/useOldLang';
import useShowTransitionDeprecated from '../../hooks/useShowTransitionDeprecated';
@ -68,7 +68,8 @@ const File: FC<OwnProps> = ({
onClick,
onDateClick,
}) => {
const lang = useOldLang();
const oldLang = useOldLang();
const lang = useLang();
let elementRef = useRef<HTMLDivElement>();
if (ref) {
elementRef = ref;
@ -160,13 +161,13 @@ const File: FC<OwnProps> = ({
{!sender && Boolean(timestamp) && (
<>
<span className="bullet" />
<Link onClick={onDateClick}>{formatMediaDateTime(lang, timestamp * 1000, true)}</Link>
<Link onClick={onDateClick}>{formatMediaDateTime(oldLang, timestamp * 1000, true)}</Link>
</>
)}
</div>
</div>
{sender && Boolean(timestamp) && (
<Link onClick={onDateClick}>{formatPastTimeShort(lang, timestamp * 1000)}</Link>
<Link onClick={onDateClick}>{formatPastTimeShort(oldLang, timestamp * 1000)}</Link>
)}
</div>
);

View File

@ -233,7 +233,7 @@ const GroupChatInfo: FC<OwnProps & StateProps> = ({
className={
buildClassName('ChatInfo', className)
}
dir={!noRtl && oldLang.isRtl ? 'rtl' : undefined}
dir={!noRtl && lang.isRtl ? 'rtl' : undefined}
onClick={onClick}
>
{!noAvatar && !isTopic && (

View File

@ -10,6 +10,7 @@ import buildClassName from '../../util/buildClassName';
import { copyTextToClipboard } from '../../util/clipboard';
import { isBetween } from '../../util/math';
import useLang from '../../hooks/useLang';
import useOldLang from '../../hooks/useOldLang';
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
@ -45,7 +46,8 @@ const ManageUsernames: FC<OwnProps> = ({
sortUsernames,
sortChatUsernames,
} = getActions();
const lang = useOldLang();
const oldLang = useOldLang();
const lang = useLang();
const [usernameForConfirm, setUsernameForConfirm] = useState<ApiUsername | undefined>();
const usernameList = useMemo(() => usernames.map(({ username }) => username), [usernames]);
@ -71,9 +73,9 @@ const ManageUsernames: FC<OwnProps> = ({
const handleCopyUsername = useCallback((value: string) => {
copyTextToClipboard(`@${value}`);
showNotification({
message: lang('UsernameCopied'),
message: oldLang('UsernameCopied'),
});
}, [lang, showNotification]);
}, [oldLang, showNotification]);
const handleUsernameClick = useCallback((data: ApiUsername) => {
if (data.isEditable) {
@ -147,7 +149,7 @@ const ManageUsernames: FC<OwnProps> = ({
<>
<div className={styles.container}>
<h4 className={styles.header} dir={lang.isRtl ? 'rtl' : undefined}>
{lang('lng_usernames_subtitle')}
{oldLang('lng_usernames_subtitle')}
</h4>
<div className={styles.sortableContainer} style={`height: ${(usernames.length) * USERNAME_HEIGHT_PX}px`}>
{usernames.map((usernameData, i) => {
@ -165,7 +167,7 @@ const ManageUsernames: FC<OwnProps> = ({
onDrag={handleDrag}
onDragEnd={handleDragEnd}
style={`top: ${isDragged ? draggedTop : top}px;`}
knobStyle={`${lang.isRtl ? 'left' : 'right'}: 3rem;`}
knobStyle="inset-inline-end: 3rem;"
isDisabled={!usernameData.isActive}
>
<ListItem
@ -180,7 +182,7 @@ const ManageUsernames: FC<OwnProps> = ({
handler: () => {
handleCopyUsername(usernameData.username);
},
title: lang('Copy'),
title: oldLang('Copy'),
icon: 'copy',
},
]}
@ -193,22 +195,22 @@ const ManageUsernames: FC<OwnProps> = ({
@
{usernameData.username}
</span>
<span className="subtitle">{lang(subtitle)}</span>
<span className="subtitle">{oldLang(subtitle)}</span>
</ListItem>
</Draggable>
);
})}
</div>
<p className={styles.description} dir={lang.isRtl ? 'rtl' : undefined}>
{lang('lng_usernames_description')}
{oldLang('lng_usernames_description')}
</p>
</div>
<ConfirmDialog
isOpen={Boolean(usernameForConfirm)}
onClose={closeConfirmUsernameDialog}
title={lang(usernameForConfirm?.isActive ? 'Username.DeactivateAlertTitle' : 'Username.ActivateAlertTitle')}
text={lang(usernameForConfirm?.isActive ? 'Username.DeactivateAlertText' : 'Username.ActivateAlertText')}
confirmLabel={lang(usernameForConfirm?.isActive
title={oldLang(usernameForConfirm?.isActive ? 'Username.DeactivateAlertTitle' : 'Username.ActivateAlertTitle')}
text={oldLang(usernameForConfirm?.isActive ? 'Username.DeactivateAlertText' : 'Username.ActivateAlertText')}
confirmLabel={oldLang(usernameForConfirm?.isActive
? 'Username.DeactivateAlertHide'
: 'Username.ActivateAlertShow')}
confirmHandler={handleUsernameToggle}

View File

@ -11,7 +11,7 @@ import { REM } from './helpers/mediaDimensions';
import { useTransitionActiveKey } from '../../hooks/animations/useTransitionActiveKey';
import useForceUpdate from '../../hooks/useForceUpdate';
import useOldLang from '../../hooks/useOldLang';
import useLang from '../../hooks/useLang';
import usePrevious from '../../hooks/usePrevious';
import useResizeObserver from '../../hooks/useResizeObserver';
import useSyncEffect from '../../hooks/useSyncEffect';
@ -46,7 +46,6 @@ const PremiumProgress: FC<OwnProps> = ({
animationDirection = 'none',
className,
}) => {
const lang = useOldLang();
const floatingBadgeContentRef = useRef<HTMLDivElement>();
const parentContainerRef = useRef<HTMLDivElement>();
@ -72,6 +71,8 @@ const PremiumProgress: FC<OwnProps> = ({
const prevRightText = usePrevious(rightText);
const prevIsNegative = usePrevious(isNegative);
const lang = useLang();
const BEAK_WIDTH_PX = 28;
const PROGRESS_BORDER_RADIUS_PX = REM;
const CORNER_BEAK_THRESHOLD = BEAK_WIDTH_PX / 2 + PROGRESS_BORDER_RADIUS_PX;

View File

@ -9,6 +9,7 @@ import { selectTabState, selectUser } from '../../global/selectors';
import { LOCAL_TGS_URLS } from './helpers/animatedAssets';
import renderText from './helpers/renderText';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
@ -32,7 +33,6 @@ type StateProps = {
const CLOSE_ANIMATION_DURATION = ANIMATION_DURATION + ANIMATION_END_DELAY;
const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & StateProps) => {
const lang = useOldLang();
const {
updateGlobalPrivacySettings,
openPremiumModal,
@ -41,6 +41,10 @@ const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & Sta
setPrivacyVisibility,
loadUser,
} = getActions();
const oldLang = useOldLang();
const lang = useLang();
const userName = getUserFirstOrLastName(user);
const handleShowReadTime = useLastCallback(() => {
@ -48,7 +52,7 @@ const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & Sta
closePrivacySettingsNoticeModal();
setTimeout(() => {
showNotification({ message: lang('PremiumReadSet') });
showNotification({ message: oldLang('PremiumReadSet') });
}, CLOSE_ANIMATION_DURATION);
});
@ -61,7 +65,7 @@ const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & Sta
closePrivacySettingsNoticeModal();
setTimeout(() => {
showNotification({ message: lang('PremiumLastSeenSet') });
showNotification({ message: oldLang('PremiumLastSeenSet') });
}, CLOSE_ANIMATION_DURATION);
});
@ -98,11 +102,11 @@ const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & Sta
noLoop
/>
<h2 className={styles.header}>
{lang(isReadDate ? 'PremiumReadHeader1' : 'PremiumLastSeenHeader1')}
{oldLang(isReadDate ? 'PremiumReadHeader1' : 'PremiumLastSeenHeader1')}
</h2>
<p className={styles.desc}>
{renderText(
lang(
oldLang(
isReadDate ? 'PremiumReadText1' : 'PremiumLastSeenText1Locked',
userName,
),
@ -113,13 +117,13 @@ const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & Sta
onClick={isReadDate ? handleShowReadTime : handleShowLastSeen}
className={styles.button}
>
{lang(isReadDate ? 'PremiumReadButton1' : 'PremiumLastSeenButton1')}
{oldLang(isReadDate ? 'PremiumReadButton1' : 'PremiumLastSeenButton1')}
</Button>
<Separator className={styles.separator}>{lang('PremiumOr')}</Separator>
<h2 className={styles.header}>{lang('PremiumReadHeader2')}</h2>
<Separator className={styles.separator}>{oldLang('PremiumOr')}</Separator>
<h2 className={styles.header}>{oldLang('PremiumReadHeader2')}</h2>
<p className={styles.desc}>
{renderText(
lang(isReadDate ? 'PremiumReadText2' : 'PremiumLastSeenText2', userName),
oldLang(isReadDate ? 'PremiumReadText2' : 'PremiumLastSeenText2', userName),
['simple_markdown'],
)}
</p>
@ -128,7 +132,7 @@ const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & Sta
onClick={handleOpenPremium}
className={styles.button}
>
{lang('PremiumLastSeenButton2')}
{oldLang('PremiumLastSeenButton2')}
</Button>
</div>
</Modal>

View File

@ -1,5 +1,4 @@
import type { FC } from '../../lib/teact/teact';
import type React from '../../lib/teact/teact';
import { memo, useEffect, useMemo } from '../../lib/teact/teact';
import { getActions, withGlobal } from '../../global';
@ -18,6 +17,7 @@ import buildClassName from '../../util/buildClassName';
import renderText from './helpers/renderText';
import useIntervalForceUpdate from '../../hooks/schedulers/useIntervalForceUpdate';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
@ -109,7 +109,8 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
loadMoreProfilePhotos,
} = getActions();
const lang = useOldLang();
const oldLang = useOldLang();
const lang = useLang();
const { id: userId } = user || {};
@ -158,14 +159,14 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
if (withUpdatingStatus && !areMessagesLoaded) {
return (
<DotAnimation className="status" content={lang('Updating')} />
<DotAnimation className="status" content={oldLang('Updating')} />
);
}
if (customPeer?.subtitleKey) {
return (
<span className="status" dir="auto">
<span className="user-status" dir="auto">{lang(customPeer.subtitleKey)}</span>
<span className="user-status" dir="auto">{oldLang(customPeer.subtitleKey)}</span>
</span>
);
}
@ -182,7 +183,7 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
return undefined;
}
const translatedStatus = getUserStatus(lang, user, userStatus);
const translatedStatus = getUserStatus(oldLang, user, userStatus);
const mainUserNameClassName = buildClassName('handle', translatedStatus && 'withStatus');
return (
<span className={buildClassName('status', isUserOnline(user, userStatus, true) && 'online')}>
@ -193,7 +194,7 @@ const PrivateChatInfo: FC<OwnProps & StateProps> = ({
}
const customTitle = adminMember
? adminMember.customTitle || lang(adminMember.isOwner ? 'GroupInfo.LabelOwner' : 'GroupInfo.LabelAdmin')
? adminMember.customTitle || oldLang(adminMember.isOwner ? 'GroupInfo.LabelOwner' : 'GroupInfo.LabelAdmin')
: undefined;
function renderNameTitle() {

View File

@ -23,6 +23,7 @@ import useSelector from '../../../hooks/data/useSelector';
import useInfiniteScroll from '../../../hooks/useInfiniteScroll';
import useInputFocusOnOpen from '../../../hooks/useInputFocusOnOpen';
import useKeyboardListNavigation from '../../../hooks/useKeyboardListNavigation';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
@ -78,6 +79,7 @@ const ChatOrUserPicker: FC<OwnProps> = ({
const { loadTopics } = getActions();
const oldLang = useOldLang();
const lang = useLang();
const containerRef = useRef<HTMLDivElement>();
const topicContainerRef = useRef<HTMLDivElement>();
const searchRef = useRef<HTMLInputElement>();
@ -244,7 +246,7 @@ const ChatOrUserPicker: FC<OwnProps> = ({
function renderTopicList() {
return (
<>
<div className="modal-header modal-header-condensed" dir={oldLang.isRtl ? 'rtl' : undefined}>
<div className="modal-header modal-header-condensed" dir={lang.isRtl ? 'rtl' : undefined}>
<Button round color="translucent" size="smaller" ariaLabel={oldLang('Back')} onClick={handleHeaderBackClick}>
<Icon name="arrow-left" />
</Button>
@ -291,7 +293,7 @@ const ChatOrUserPicker: FC<OwnProps> = ({
function renderChatList() {
return (
<>
<div className="modal-header modal-header-condensed" dir={oldLang.isRtl ? 'rtl' : undefined}>
<div className="modal-header modal-header-condensed" dir={lang.isRtl ? 'rtl' : undefined}>
<Button
round
color="translucent"

View File

@ -3,8 +3,8 @@ import { type TeactNode } from '../../../lib/teact/teact';
import { IS_IOS } from '../../../util/browser/windowEnvironment';
import buildClassName from '../../../util/buildClassName';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import RippleEffect from '../../ui/RippleEffect';
@ -43,7 +43,7 @@ const PickerItem = ({
onClick,
onDisabledClick,
}: OwnProps) => {
const lang = useOldLang();
const lang = useLang();
const isClickable = !inactive && !disabled;
const handleClick = useLastCallback(() => {

View File

@ -100,6 +100,10 @@
background-color: var(--background-color);
}
.info-row {
line-height: 1.375;
}
.info.has-tags .subtitle {
height: unset;
line-height: inherit;

View File

@ -166,7 +166,7 @@
position: absolute;
z-index: 1;
bottom: 0.0625rem;
left: 2.875rem;
inset-inline-start: 2.875rem;
font-size: 0.5rem;
font-weight: var(--font-weight-medium);

View File

@ -274,20 +274,20 @@ const LeftMainHeader: FC<OwnProps & StateProps> = ({
className="left-header"
data-tauri-drag-region={IS_TAURI && IS_MAC_OS ? true : undefined}
>
{oldLang.isRtl && <div className="DropdownMenuFiller" />}
{lang.isRtl && <div className="DropdownMenuFiller" />}
<DropdownMenu
trigger={MainButton}
footer={version}
className={buildClassName(
'main-menu',
oldLang.isRtl && 'rtl',
shouldHideSearch && oldLang.isRtl && 'right-aligned',
shouldDisableDropdownMenuTransitionRef.current && oldLang.isRtl && 'disable-transition',
lang.isRtl && 'rtl',
shouldHideSearch && lang.isRtl && 'right-aligned',
shouldDisableDropdownMenuTransitionRef.current && lang.isRtl && 'disable-transition',
)}
forceOpen={isBotMenuOpen}
positionX={shouldHideSearch && oldLang.isRtl ? 'right' : 'left'}
positionX={shouldHideSearch && lang.isRtl ? 'right' : 'left'}
transformOriginX={IS_TAURI && IS_MAC_OS && !isFullscreen ? 90 : undefined}
onTransitionEnd={oldLang.isRtl ? handleDropdownMenuTransitionEnd : undefined}
onTransitionEnd={lang.isRtl ? handleDropdownMenuTransitionEnd : undefined}
>
<LeftSideMenuItems
onSelectArchived={onSelectArchived}

View File

@ -160,7 +160,7 @@ function PrivacyMessages({
return (
<div className="settings-item">
<h4 className="settings-item-header" dir={oldLang.isRtl ? 'rtl' : undefined}>
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>
{lang('RemoveFeeTitle')}
</h4>
<ListItem
@ -197,7 +197,7 @@ function PrivacyMessages({
return (
<>
<div className="settings-item">
<h4 className="settings-item-header" dir={oldLang.isRtl ? 'rtl' : undefined}>
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>
{oldLang('PrivacyMessagesTitle')}
</h4>
<RadioGroup
@ -206,7 +206,7 @@ function PrivacyMessages({
onChange={handleChange}
selected={selectedValue}
/>
<p className="settings-item-description-larger" dir={oldLang.isRtl ? 'rtl' : undefined}>
<p className="settings-item-description-larger" dir={lang.isRtl ? 'rtl' : undefined}>
{privacyDescription}
</p>
</div>

View File

@ -236,7 +236,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
</div>
<div className="settings-item">
<h4 className="settings-item-header" dir={oldLang.isRtl ? 'rtl' : undefined}>{oldLang('PrivacyTitle')}</h4>
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>{oldLang('PrivacyTitle')}</h4>
<ListItem
narrow
@ -391,7 +391,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
{canChangeSensitive && (
<div className="settings-item fluid-container">
<h4 className="settings-item-header" dir={oldLang.isRtl ? 'rtl' : undefined}>
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>
{oldLang('lng_settings_sensitive_title')}
</h4>
<Checkbox
@ -419,7 +419,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
{canDisplayAutoarchiveSetting && (
<div className="settings-item">
<h4 className="settings-item-header" dir={oldLang.isRtl ? 'rtl' : undefined}>
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>
{oldLang('NewChatsFromNonContacts')}
</h4>
<Checkbox
@ -432,7 +432,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
)}
<div className="settings-item">
<h4 className="settings-item-header" dir={oldLang.isRtl ? 'rtl' : undefined}>
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>
{oldLang('lng_settings_window_system')}
</h4>
<Checkbox
@ -443,7 +443,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
</div>
<div className="settings-item">
<h4 className="settings-item-header" dir={oldLang.isRtl ? 'rtl' : undefined}>
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>
{lang('DeleteMyAccount')}
</h4>
<ListItem

View File

@ -348,7 +348,7 @@ function PrivacySubsection({
return (
<>
<div className="settings-item">
<h4 className="settings-item-header" dir={oldLang.isRtl ? 'rtl' : undefined}>{headerText}</h4>
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>{headerText}</h4>
<RadioGroup
name={`visibility-${privacyKey}`}
options={visibilityOptions}
@ -356,12 +356,12 @@ function PrivacySubsection({
selected={privacy?.visibility}
/>
{descriptionText && (
<p className="settings-item-description-larger" dir={oldLang.isRtl ? 'rtl' : undefined}>{descriptionText}</p>
<p className="settings-item-description-larger" dir={lang.isRtl ? 'rtl' : undefined}>{descriptionText}</p>
)}
</div>
{!isPremiumRequired && (primaryExceptionLists.shouldShowAllowed || primaryExceptionLists.shouldShowDenied) && (
<div className="settings-item">
<h4 className="settings-item-header" dir={oldLang.isRtl ? 'rtl' : undefined}>
<h4 className="settings-item-header" dir={lang.isRtl ? 'rtl' : undefined}>
{oldLang('PrivacyExceptions')}
</h4>
{primaryExceptionLists.shouldShowAllowed && (

View File

@ -143,7 +143,7 @@ const NewContactModal: FC<OwnProps & StateProps> = ({
function renderAddContact() {
return (
<>
<div className="NewContactModal__profile" dir={oldLang.isRtl ? 'rtl' : undefined}>
<div className="NewContactModal__profile" dir={lang.isRtl ? 'rtl' : undefined}>
<Avatar
size="jumbo"
peer={renderingUser}

View File

@ -394,7 +394,7 @@ const PremiumMainModal: FC<OwnProps & StateProps> = ({
}
return (
<div className={styles.footerText} dir={oldLang.isRtl ? 'rtl' : undefined}>
<div className={styles.footerText} dir={lang.isRtl ? 'rtl' : undefined}>
{renderTextWithEntities({
text: promo.statusText,
entities: promo.statusEntities,
@ -473,7 +473,7 @@ const PremiumMainModal: FC<OwnProps & StateProps> = ({
})}
<div
className={buildClassName(styles.footerText, styles.primaryFooterText)}
dir={oldLang.isRtl ? 'rtl' : undefined}
dir={lang.isRtl ? 'rtl' : undefined}
>
<p>
{renderText(oldLang('AboutPremiumDescription'), ['simple_markdown'])}

View File

@ -7,6 +7,7 @@ import type { ApiPremiumGiftCodeOption, ApiPremiumSubscriptionOption } from '../
import buildClassName from '../../../util/buildClassName';
import { formatCurrencyAsString } from '../../../util/formatCurrency';
import useLang from '../../../hooks/useLang';
import useOldLang from '../../../hooks/useOldLang';
import styles from './PremiumSubscriptionOption.module.scss';
@ -25,6 +26,7 @@ const PremiumSubscriptionOption: FC<OwnProps> = ({
onChange, className, isGiveaway,
}) => {
const oldLang = useOldLang();
const lang = useLang();
const {
months, amount, currency,
@ -52,7 +54,7 @@ const PremiumSubscriptionOption: FC<OwnProps> = ({
(checked && !isGiveaway) && styles.active,
className,
)}
dir={oldLang.isRtl ? 'rtl' : undefined}
dir={lang.isRtl ? 'rtl' : undefined}
>
<input
className={styles.input}

View File

@ -602,7 +602,7 @@ function MiddleColumn({
/>
)}
{isPinnedMessageList && canUnpin && (
<div className="middle-column-footer-button-container" dir={oldLang.isRtl ? 'rtl' : undefined}>
<div className="middle-column-footer-button-container" dir={lang.isRtl ? 'rtl' : undefined}>
<Button
size="tiny"
fluid
@ -616,7 +616,7 @@ function MiddleColumn({
</div>
)}
{canShowOpenChatButton && (
<div className="middle-column-footer-button-container" dir={oldLang.isRtl ? 'rtl' : undefined}>
<div className="middle-column-footer-button-container" dir={lang.isRtl ? 'rtl' : undefined}>
<Button
size="tiny"
fluid
@ -640,7 +640,7 @@ function MiddleColumn({
{(
isMobile && (renderingCanSubscribe || (renderingShouldJoinToSend && !renderingShouldSendJoinRequest))
) && (
<div className="middle-column-footer-button-container" dir={oldLang.isRtl ? 'rtl' : undefined}>
<div className="middle-column-footer-button-container" dir={lang.isRtl ? 'rtl' : undefined}>
<Button
size="tiny"
fluid
@ -653,7 +653,7 @@ function MiddleColumn({
</div>
)}
{isMobile && renderingShouldSendJoinRequest && (
<div className="middle-column-footer-button-container" dir={oldLang.isRtl ? 'rtl' : undefined}>
<div className="middle-column-footer-button-container" dir={lang.isRtl ? 'rtl' : undefined}>
<Button
size="tiny"
fluid
@ -666,7 +666,7 @@ function MiddleColumn({
</div>
)}
{isMobile && renderingCanStartBot && (
<div className="middle-column-footer-button-container" dir={oldLang.isRtl ? 'rtl' : undefined}>
<div className="middle-column-footer-button-container" dir={lang.isRtl ? 'rtl' : undefined}>
<Button
size="tiny"
fluid
@ -679,7 +679,7 @@ function MiddleColumn({
</div>
)}
{isMobile && renderingCanRestartBot && (
<div className="middle-column-footer-button-container" dir={oldLang.isRtl ? 'rtl' : undefined}>
<div className="middle-column-footer-button-container" dir={lang.isRtl ? 'rtl' : undefined}>
<Button
size="tiny"
fluid
@ -692,7 +692,7 @@ function MiddleColumn({
</div>
)}
{isMobile && renderingCanUnblock && (
<div className="middle-column-footer-button-container" dir={oldLang.isRtl ? 'rtl' : undefined}>
<div className="middle-column-footer-button-container" dir={lang.isRtl ? 'rtl' : undefined}>
<Button
size="tiny"
fluid

View File

@ -150,7 +150,7 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
onCloseAnimationEnd={handleCloseAnimationEnd}
>
{canShowFilters && (
<div className="Reactions" dir={oldLang.isRtl ? 'rtl' : undefined}>
<div className="Reactions" dir={lang.isRtl ? 'rtl' : undefined}>
<Button
className={buildClassName(!chosenTab && 'chosen')}
size="tiny"
@ -185,7 +185,7 @@ const ReactorListModal: FC<OwnProps & StateProps> = ({
</div>
)}
<div dir={oldLang.isRtl ? 'rtl' : undefined} className="reactor-list-wrapper">
<div dir={lang.isRtl ? 'rtl' : undefined} className="reactor-list-wrapper">
{viewportIds?.length ? (
<InfiniteScroll
className="reactor-list custom-scroll"

View File

@ -532,7 +532,7 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
}
return (
<div className="modal-header-condensed" dir={oldLang.isRtl ? 'rtl' : undefined}>
<div className="modal-header-condensed" dir={lang.isRtl ? 'rtl' : undefined}>
<Button round color="translucent" size="smaller" ariaLabel="Cancel attachments" onClick={onClear}>
<Icon name="close" />
</Button>

View File

@ -154,7 +154,7 @@ const CustomSendMenu: FC<OwnProps> = ({
'CustomSendMenu_items',
areItemsHidden && 'CustomSendMenu_items-hidden',
)}
dir={oldLang.isRtl ? 'rtl' : undefined}
dir={lang.isRtl ? 'rtl' : undefined}
>
{onSendSilent && <MenuItem icon="mute" onClick={onSendSilent}>{oldLang('SendWithoutSound')}</MenuItem>}
{canSchedule && onSendSchedule && (

View File

@ -34,6 +34,7 @@ import { isSelectionInsideInput } from './helpers/selection';
import useAppLayout from '../../../hooks/useAppLayout';
import useDerivedState from '../../../hooks/useDerivedState';
import useFlag from '../../../hooks/useFlag';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import useInputCustomEmojis from './hooks/useInputCustomEmojis';
@ -167,6 +168,7 @@ const MessageInput: FC<OwnProps & StateProps> = ({
const absoluteContainerRef = useRef<HTMLDivElement>();
const oldLang = useOldLang();
const lang = useLang();
const isContextMenuOpenRef = useRef(false);
const [isTextFormatterOpen, openTextFormatter, closeTextFormatter] = useFlag();
const [textFormatterAnchorPosition, setTextFormatterAnchorPosition] = useState<IAnchorPosition>();
@ -572,7 +574,7 @@ const MessageInput: FC<OwnProps & StateProps> = ({
const placeholderAriaLabel = typeof placeholder === 'string' ? placeholder : undefined;
return (
<div id={id} onClick={shouldSuppressFocus ? onSuppressedFocus : undefined} dir={oldLang.isRtl ? 'rtl' : undefined}>
<div id={id} onClick={shouldSuppressFocus ? onSuppressedFocus : undefined} dir={lang.isRtl ? 'rtl' : undefined}>
<div
className={buildClassName('custom-scroll', SCROLLER_CLASS, isNeedPremium && 'is-need-premium')}
onScroll={onScroll}

View File

@ -79,7 +79,7 @@ const CommentButton: FC<OwnProps> = ({
function renderRecentRepliers() {
return (
Boolean(recentRepliers?.length) && (
<div className="recent-repliers" dir={oldLang.isRtl ? 'rtl' : 'ltr'}>
<div className="recent-repliers" dir={lang.isRtl ? 'rtl' : 'ltr'}>
{recentRepliers.map((peer) => (
<Avatar
key={peer.id}
@ -112,7 +112,7 @@ const CommentButton: FC<OwnProps> = ({
isLoading && 'loading',
asActionButton && 'as-action-button',
)}
dir={oldLang.isRtl ? 'rtl' : 'ltr'}
dir={lang.isRtl ? 'rtl' : 'ltr'}
onClick={handleClick}
role="button"
tabIndex={0}

View File

@ -404,7 +404,7 @@ const MessageContextMenu: FC<OwnProps> = ({
'MessageContextMenu_items scrollable-content custom-scroll',
areItemsHidden && 'MessageContextMenu_items-hidden',
)}
dir={oldLang.isRtl ? 'rtl' : undefined}
dir={lang.isRtl ? 'rtl' : undefined}
>
{shouldShowGiftButton
&& (
@ -504,7 +504,7 @@ const MessageContextMenu: FC<OwnProps> = ({
disabled={!canShowReactionsCount && !seenByDatesCount}
>
<span className="MessageContextMenu--seen-by-label-wrapper">
<span className="MessageContextMenu--seen-by-label" dir={oldLang.isRtl ? 'rtl' : undefined}>
<span className="MessageContextMenu--seen-by-label" dir={lang.isRtl ? 'rtl' : undefined}>
{canShowReactionsCount && message.reactors?.count ? (
canShowSeenBy && seenByDatesCount
? oldLang(

View File

@ -19,7 +19,6 @@ import useDynamicColorListener from '../../../hooks/stickers/useDynamicColorList
import useEnsureStory from '../../../hooks/useEnsureStory';
import useLang from '../../../hooks/useLang';
import useLastCallback from '../../../hooks/useLastCallback';
import useOldLang from '../../../hooks/useOldLang';
import Audio from '../../common/Audio';
import Document from '../../common/Document';
@ -98,7 +97,6 @@ const WebPage: FC<OwnProps & StateProps> = ({
const { openUrl, openTelegramLink } = getActions();
const stickersRef = useRef<HTMLDivElement>();
const oldLang = useOldLang();
const lang = useLang();
const handleMediaClick = useLastCallback(() => {
@ -191,7 +189,7 @@ const WebPage: FC<OwnProps & StateProps> = ({
<PeerColorWrapper
className={className}
data-initial={(siteName || displayUrl)[0]}
dir={oldLang.isRtl ? 'rtl' : 'auto'}
dir={lang.isRtl ? 'rtl' : 'auto'}
onClick={handleContainerClick}
>
<div className={buildClassName(

View File

@ -170,7 +170,7 @@ const StarPaymentModal = ({
onClose={closeStarsPaymentModal}
>
<BalanceBlock balance={starsBalanceState?.balance} className={styles.modalBalance} />
<div className={styles.paymentImages} dir={oldLang.isRtl ? 'ltr' : 'rtl'}>
<div className={styles.paymentImages} dir={lang.isRtl ? 'ltr' : 'rtl'}>
{paidMediaMessage ? (
<PaidMediaThumb media={paidMediaMessage.content.paidMedia!.extendedMedia} />
) : inviteCustomPeer ? (

View File

@ -159,7 +159,7 @@ const Checkout: FC<OwnProps> = ({
function renderTos(url: string) {
return (
<Checkbox
label={renderTosLink(url, oldLang.isRtl)}
label={renderTosLink(url, lang.isRtl)}
name="checkout_tos"
checked={Boolean(isTosAccepted)}
className={styles.tosCheckbox}

View File

@ -561,7 +561,7 @@ const PaymentModal: FC<OwnProps & StateProps> = ({
onClose={closeModal}
onCloseAnimationEnd={handleModalClose}
>
<div className="header" dir={oldLang.isRtl ? 'rtl' : undefined}>
<div className="header" dir={lang.isRtl ? 'rtl' : undefined}>
<Button
className="close-button"
color="translucent"

View File

@ -7,7 +7,7 @@ import buildClassName from '../../util/buildClassName';
import { getIsMobile } from '../../hooks/useAppLayout';
import useHorizontalScroll from '../../hooks/useHorizontalScroll';
import useOldLang from '../../hooks/useOldLang';
import useLang from '../../hooks/useLang';
import StoryRibbonButton from './StoryRibbonButton';
@ -33,7 +33,7 @@ function StoryRibbon({
chatsById,
isClosing,
}: OwnProps & StateProps) {
const lang = useOldLang();
const lang = useLang();
const fullClassName = buildClassName(
styles.root,
!orderedPeerIds.length && styles.hidden,

View File

@ -26,11 +26,17 @@
}
.avatar {
--_gradient-rotation: 90deg;
z-index: 1;
:dir(rtl) & {
--_gradient-rotation: -90deg;
}
&:not(:first-child):before {
mask-composite: exclude;
mask-image: linear-gradient(90deg, #fff 75%, transparent 0);
mask-image: linear-gradient(var(--_gradient-rotation), #fff 75%, transparent 0);
}
&:global(.animating) {

View File

@ -10,7 +10,7 @@ import { ANIMATION_END_DELAY, PREVIEW_AVATAR_COUNT } from '../../config';
import { selectIsForumPanelOpen, selectPerformanceSettingsValue, selectTabState } from '../../global/selectors';
import { animateClosing, animateOpening, ANIMATION_DURATION } from './helpers/ribbonAnimation';
import useOldLang from '../../hooks/useOldLang';
import useLang from '../../hooks/useLang';
import useShowTransition from '../../hooks/useShowTransition';
import useStoryPreloader from './hooks/useStoryPreloader';
@ -50,7 +50,7 @@ function StoryToggler({
}: OwnProps & StateProps) {
const { toggleStoryRibbon } = getActions();
const lang = useOldLang();
const lang = useLang();
const peers = useMemo(() => {
if (orderedPeerIds.length === 1) {
@ -117,7 +117,7 @@ function StoryToggler({
type="button"
id="StoryToggler"
className={styles.root}
aria-label={lang('Chat.Context.Peer.OpenStory')}
aria-label={lang('AriaStoryTogglerOpen')}
onClick={() => toggleStoryRibbon({ isShown: true, isArchived })}
dir={lang.isRtl ? 'rtl' : undefined}
>

View File

@ -168,8 +168,8 @@
grid-row: span 2;
align-self: center;
margin-right: 0.5rem;
margin-left: auto;
margin-inline-start: auto;
margin-inline-end: 0.5rem;
font-size: 1.25rem;
color: var(--color-text-secondary);

View File

@ -16,8 +16,8 @@ import { REM } from '../common/helpers/mediaDimensions';
import renderText from '../common/helpers/renderText';
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import Avatar from '../common/Avatar';
import Icon from '../common/icons/Icon';
@ -85,7 +85,7 @@ const Checkbox: FC<OwnProps> = ({
onCheck,
onClickLabel,
}) => {
const lang = useOldLang();
const lang = useLang();
const labelRef = useRef<HTMLLabelElement>();
const [showNested, setShowNested] = useState(false);
const renderingUser = useCurrentOrPrev(user, true);

View File

@ -7,7 +7,7 @@ import { memo } from '../../lib/teact/teact';
import { IS_TAURI } from '../../util/browser/globalEnvironment';
import buildClassName from '../../util/buildClassName';
import useOldLang from '../../hooks/useOldLang';
import useLang from '../../hooks/useLang';
type OwnProps = {
ref?: ElementRef<HTMLInputElement>;
@ -56,7 +56,7 @@ const InputText: FC<OwnProps> = ({
onBlur,
onPaste,
}) => {
const lang = useOldLang();
const lang = useLang();
const labelText = error || success || label;
const fullClassName = buildClassName(
'input-group',

View File

@ -90,7 +90,7 @@
}
> .ListItem-main-icon {
margin-right: 1.75rem;
margin-inline-end: 1.75rem;
font-size: 1.5rem;
color: var(--color-text-secondary);
}
@ -234,7 +234,7 @@
}
.Avatar {
margin-right: 0.5rem;
margin-inline-end: 0.5rem;
}
.info {
@ -368,15 +368,6 @@
}
&[dir="rtl"] {
.ListItem-button {
padding: 0.5625rem 0.5625rem 0.5625rem 0.6875rem;
}
.Avatar {
margin-right: 0;
margin-left: 0.5rem;
}
.info > .status {
width: 100%;
}

View File

@ -12,8 +12,8 @@ import renderText from '../common/helpers/renderText';
import useContextMenuHandlers from '../../hooks/useContextMenuHandlers';
import { useFastClick } from '../../hooks/useFastClick';
import useFlag from '../../hooks/useFlag';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import Icon from '../common/icons/Icon';
import Button from './Button';
@ -201,7 +201,7 @@ const ListItem = ({
}
});
const lang = useOldLang();
const lang = useLang();
const fullClassName = buildClassName(
'ListItem',

View File

@ -1,5 +1,4 @@
import type { FC } from '../../lib/teact/teact';
import type React from '../../lib/teact/teact';
import type { IconName } from '../../types/icons';
@ -7,8 +6,8 @@ import { IS_TEST } from '../../config';
import buildClassName from '../../util/buildClassName';
import useAppLayout from '../../hooks/useAppLayout';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import Icon from '../common/icons/Icon';
@ -59,7 +58,7 @@ const MenuItem: FC<MenuItemProps> = (props) => {
withPreventDefaultOnMouseDown,
} = props;
const lang = useOldLang();
const lang = useLang();
const { isTouchScreen } = useAppLayout();
const handleClick = useLastCallback((e: React.MouseEvent<HTMLDivElement>) => {
if (disabled || !onClick) {

View File

@ -4,7 +4,7 @@ import { memo } from '../../lib/teact/teact';
import buildClassName from '../../util/buildClassName';
import useOldLang from '../../hooks/useOldLang';
import useLang from '../../hooks/useLang';
import Spinner from './Spinner';
@ -49,7 +49,7 @@ const Radio: FC<OwnProps> = ({
onSubLabelClick,
isCanCheckedInDisabled,
}) => {
const lang = useOldLang();
const lang = useLang();
const fullClassName = buildClassName(
'Radio',

View File

@ -4,7 +4,7 @@ import { memo, useCallback, useMemo } from '../../lib/teact/teact';
import buildClassName from '../../util/buildClassName';
import useOldLang from '../../hooks/useOldLang';
import useLang from '../../hooks/useLang';
import './RangeSlider.scss';
@ -39,7 +39,7 @@ const RangeSlider: FC<OwnProps> = ({
onChange,
isCenteredLayout,
}) => {
const lang = useOldLang();
const lang = useLang();
const handleChange = useCallback((event: ChangeEvent<HTMLInputElement>) => {
onChange(Number(event.currentTarget.value));
}, [onChange]);

View File

@ -158,7 +158,7 @@ const SearchInput: FC<OwnProps> = ({
<div
className={buildClassName('SearchInput', className, isInputFocused && 'has-focus')}
onClick={onClick}
dir={oldLang.isRtl ? 'rtl' : undefined}
dir={lang.isRtl ? 'rtl' : undefined}
>
<Transition
name="fade"

View File

@ -8,7 +8,7 @@ import { IS_ANDROID, IS_IOS } from '../../util/browser/windowEnvironment';
import buildClassName from '../../util/buildClassName';
import useHorizontalScroll from '../../hooks/useHorizontalScroll';
import useOldLang from '../../hooks/useOldLang';
import useLang from '../../hooks/useLang';
import usePreviousDeprecated from '../../hooks/usePreviousDeprecated';
import Tab from './Tab';
@ -29,8 +29,8 @@ type OwnProps = {
activeTab: number;
className?: string;
tabClassName?: string;
onSwitchTab: (index: number) => void;
contextRootElementSelector?: string;
onSwitchTab: (index: number) => void;
};
const TAB_SCROLL_THRESHOLD_PX = 16;
@ -48,6 +48,8 @@ const TabList = ({
const containerRef = useRef<HTMLDivElement>();
const previousActiveTab = usePreviousDeprecated(activeTab);
const lang = useLang();
useHorizontalScroll(containerRef, undefined, true);
// Scroll container to place active tab in the center
@ -74,8 +76,6 @@ const TabList = ({
animateHorizontalScroll(container, newLeft, SCROLL_DURATION);
}, [activeTab]);
const lang = useOldLang();
return (
<div
className={buildClassName('TabList', 'no-scrollbar', className)}

View File

@ -1728,6 +1728,7 @@ export interface LangPair {
'UserNoteTitle': undefined;
'UserNoteHint': undefined;
'EditUserNoteHint': undefined;
'AriaStoryTogglerOpen': undefined;
}
export interface LangPairWithVariables<V = LangVariable> {