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

View File

@ -6,7 +6,7 @@ import type { AvatarSize } from './Avatar';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import useOldLang from '../../hooks/useOldLang'; import useLang from '../../hooks/useLang';
import Avatar, { AVATAR_SIZES } from './Avatar'; import Avatar, { AVATAR_SIZES } from './Avatar';
@ -29,7 +29,7 @@ const AvatarList: FC<OwnProps> = ({
limit = DEFAULT_LIMIT, limit = DEFAULT_LIMIT,
badgeText, badgeText,
}) => { }) => {
const lang = useOldLang(); const lang = useLang();
const pxSize = typeof size === 'number' ? size : AVATAR_SIZES[size]; 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 { getIsMobile } from '../../hooks/useAppLayout';
import { useFastClick } from '../../hooks/useFastClick'; import { useFastClick } from '../../hooks/useFastClick';
import useOldLang from '../../hooks/useOldLang'; import useLang from '../../hooks/useLang';
import TopicIcon from './TopicIcon'; import TopicIcon from './TopicIcon';
@ -47,7 +47,7 @@ const ChatForumLastMessage = ({
const lastMessageRef = useRef<HTMLDivElement>(); const lastMessageRef = useRef<HTMLDivElement>();
const mainColumnRef = useRef<HTMLDivElement>(); const mainColumnRef = useRef<HTMLDivElement>();
const lang = useOldLang(); const lang = useLang();
const [lastActiveTopic, ...otherTopics] = useMemo(() => { const [lastActiveTopic, ...otherTopics] = useMemo(() => {
if (!topics) { if (!topics) {

View File

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

View File

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

View File

@ -1,9 +1,9 @@
import type { FC } from '../../lib/teact/teact'; import { memo } from '@teact';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import renderText from './helpers/renderText'; import renderText from './helpers/renderText';
import useOldLang from '../../hooks/useOldLang'; import useLang from '../../hooks/useLang';
import './DotAnimation.scss'; import './DotAnimation.scss';
@ -12,8 +12,8 @@ type OwnProps = {
className?: string; className?: string;
}; };
const DotAnimation: FC<OwnProps> = ({ content, className }) => { const DotAnimation = ({ content, className }: OwnProps) => {
const lang = useOldLang(); const lang = useLang();
return ( return (
<span className={buildClassName('DotAnimation', className)} dir={lang.isRtl ? 'rtl' : 'auto'}> <span className={buildClassName('DotAnimation', className)} dir={lang.isRtl ? 'rtl' : 'auto'}>
{renderText(content)} {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 { ElementRef, FC } from '../../lib/teact/teact';
import type React from '../../lib/teact/teact';
import { import {
memo, useMemo, useRef, useState, memo, useMemo, useRef, useState,
} from '../../lib/teact/teact'; } from '../../lib/teact/teact';
@ -15,6 +14,7 @@ import renderText from './helpers/renderText';
import useAppLayout from '../../hooks/useAppLayout'; import useAppLayout from '../../hooks/useAppLayout';
import useCanvasBlur from '../../hooks/useCanvasBlur'; import useCanvasBlur from '../../hooks/useCanvasBlur';
import useLang from '../../hooks/useLang';
import useMediaTransitionDeprecated from '../../hooks/useMediaTransitionDeprecated'; import useMediaTransitionDeprecated from '../../hooks/useMediaTransitionDeprecated';
import useOldLang from '../../hooks/useOldLang'; import useOldLang from '../../hooks/useOldLang';
import useShowTransitionDeprecated from '../../hooks/useShowTransitionDeprecated'; import useShowTransitionDeprecated from '../../hooks/useShowTransitionDeprecated';
@ -68,7 +68,8 @@ const File: FC<OwnProps> = ({
onClick, onClick,
onDateClick, onDateClick,
}) => { }) => {
const lang = useOldLang(); const oldLang = useOldLang();
const lang = useLang();
let elementRef = useRef<HTMLDivElement>(); let elementRef = useRef<HTMLDivElement>();
if (ref) { if (ref) {
elementRef = ref; elementRef = ref;
@ -160,13 +161,13 @@ const File: FC<OwnProps> = ({
{!sender && Boolean(timestamp) && ( {!sender && Boolean(timestamp) && (
<> <>
<span className="bullet" /> <span className="bullet" />
<Link onClick={onDateClick}>{formatMediaDateTime(lang, timestamp * 1000, true)}</Link> <Link onClick={onDateClick}>{formatMediaDateTime(oldLang, timestamp * 1000, true)}</Link>
</> </>
)} )}
</div> </div>
</div> </div>
{sender && Boolean(timestamp) && ( {sender && Boolean(timestamp) && (
<Link onClick={onDateClick}>{formatPastTimeShort(lang, timestamp * 1000)}</Link> <Link onClick={onDateClick}>{formatPastTimeShort(oldLang, timestamp * 1000)}</Link>
)} )}
</div> </div>
); );

View File

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

View File

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

View File

@ -11,7 +11,7 @@ import { REM } from './helpers/mediaDimensions';
import { useTransitionActiveKey } from '../../hooks/animations/useTransitionActiveKey'; import { useTransitionActiveKey } from '../../hooks/animations/useTransitionActiveKey';
import useForceUpdate from '../../hooks/useForceUpdate'; import useForceUpdate from '../../hooks/useForceUpdate';
import useOldLang from '../../hooks/useOldLang'; import useLang from '../../hooks/useLang';
import usePrevious from '../../hooks/usePrevious'; import usePrevious from '../../hooks/usePrevious';
import useResizeObserver from '../../hooks/useResizeObserver'; import useResizeObserver from '../../hooks/useResizeObserver';
import useSyncEffect from '../../hooks/useSyncEffect'; import useSyncEffect from '../../hooks/useSyncEffect';
@ -46,7 +46,6 @@ const PremiumProgress: FC<OwnProps> = ({
animationDirection = 'none', animationDirection = 'none',
className, className,
}) => { }) => {
const lang = useOldLang();
const floatingBadgeContentRef = useRef<HTMLDivElement>(); const floatingBadgeContentRef = useRef<HTMLDivElement>();
const parentContainerRef = useRef<HTMLDivElement>(); const parentContainerRef = useRef<HTMLDivElement>();
@ -72,6 +71,8 @@ const PremiumProgress: FC<OwnProps> = ({
const prevRightText = usePrevious(rightText); const prevRightText = usePrevious(rightText);
const prevIsNegative = usePrevious(isNegative); const prevIsNegative = usePrevious(isNegative);
const lang = useLang();
const BEAK_WIDTH_PX = 28; const BEAK_WIDTH_PX = 28;
const PROGRESS_BORDER_RADIUS_PX = REM; const PROGRESS_BORDER_RADIUS_PX = REM;
const CORNER_BEAK_THRESHOLD = BEAK_WIDTH_PX / 2 + PROGRESS_BORDER_RADIUS_PX; 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 { LOCAL_TGS_URLS } from './helpers/animatedAssets';
import renderText from './helpers/renderText'; import renderText from './helpers/renderText';
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';
@ -32,7 +33,6 @@ type StateProps = {
const CLOSE_ANIMATION_DURATION = ANIMATION_DURATION + ANIMATION_END_DELAY; const CLOSE_ANIMATION_DURATION = ANIMATION_DURATION + ANIMATION_END_DELAY;
const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & StateProps) => { const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & StateProps) => {
const lang = useOldLang();
const { const {
updateGlobalPrivacySettings, updateGlobalPrivacySettings,
openPremiumModal, openPremiumModal,
@ -41,6 +41,10 @@ const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & Sta
setPrivacyVisibility, setPrivacyVisibility,
loadUser, loadUser,
} = getActions(); } = getActions();
const oldLang = useOldLang();
const lang = useLang();
const userName = getUserFirstOrLastName(user); const userName = getUserFirstOrLastName(user);
const handleShowReadTime = useLastCallback(() => { const handleShowReadTime = useLastCallback(() => {
@ -48,7 +52,7 @@ const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & Sta
closePrivacySettingsNoticeModal(); closePrivacySettingsNoticeModal();
setTimeout(() => { setTimeout(() => {
showNotification({ message: lang('PremiumReadSet') }); showNotification({ message: oldLang('PremiumReadSet') });
}, CLOSE_ANIMATION_DURATION); }, CLOSE_ANIMATION_DURATION);
}); });
@ -61,7 +65,7 @@ const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & Sta
closePrivacySettingsNoticeModal(); closePrivacySettingsNoticeModal();
setTimeout(() => { setTimeout(() => {
showNotification({ message: lang('PremiumLastSeenSet') }); showNotification({ message: oldLang('PremiumLastSeenSet') });
}, CLOSE_ANIMATION_DURATION); }, CLOSE_ANIMATION_DURATION);
}); });
@ -98,11 +102,11 @@ const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & Sta
noLoop noLoop
/> />
<h2 className={styles.header}> <h2 className={styles.header}>
{lang(isReadDate ? 'PremiumReadHeader1' : 'PremiumLastSeenHeader1')} {oldLang(isReadDate ? 'PremiumReadHeader1' : 'PremiumLastSeenHeader1')}
</h2> </h2>
<p className={styles.desc}> <p className={styles.desc}>
{renderText( {renderText(
lang( oldLang(
isReadDate ? 'PremiumReadText1' : 'PremiumLastSeenText1Locked', isReadDate ? 'PremiumReadText1' : 'PremiumLastSeenText1Locked',
userName, userName,
), ),
@ -113,13 +117,13 @@ const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & Sta
onClick={isReadDate ? handleShowReadTime : handleShowLastSeen} onClick={isReadDate ? handleShowReadTime : handleShowLastSeen}
className={styles.button} className={styles.button}
> >
{lang(isReadDate ? 'PremiumReadButton1' : 'PremiumLastSeenButton1')} {oldLang(isReadDate ? 'PremiumReadButton1' : 'PremiumLastSeenButton1')}
</Button> </Button>
<Separator className={styles.separator}>{lang('PremiumOr')}</Separator> <Separator className={styles.separator}>{oldLang('PremiumOr')}</Separator>
<h2 className={styles.header}>{lang('PremiumReadHeader2')}</h2> <h2 className={styles.header}>{oldLang('PremiumReadHeader2')}</h2>
<p className={styles.desc}> <p className={styles.desc}>
{renderText( {renderText(
lang(isReadDate ? 'PremiumReadText2' : 'PremiumLastSeenText2', userName), oldLang(isReadDate ? 'PremiumReadText2' : 'PremiumLastSeenText2', userName),
['simple_markdown'], ['simple_markdown'],
)} )}
</p> </p>
@ -128,7 +132,7 @@ const PrivacySettingsNoticeModal = ({ isOpen, isReadDate, user }: OwnProps & Sta
onClick={handleOpenPremium} onClick={handleOpenPremium}
className={styles.button} className={styles.button}
> >
{lang('PremiumLastSeenButton2')} {oldLang('PremiumLastSeenButton2')}
</Button> </Button>
</div> </div>
</Modal> </Modal>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -160,7 +160,7 @@ function PrivacyMessages({
return ( return (
<div className="settings-item"> <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')} {lang('RemoveFeeTitle')}
</h4> </h4>
<ListItem <ListItem
@ -197,7 +197,7 @@ function PrivacyMessages({
return ( return (
<> <>
<div className="settings-item"> <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')} {oldLang('PrivacyMessagesTitle')}
</h4> </h4>
<RadioGroup <RadioGroup
@ -206,7 +206,7 @@ function PrivacyMessages({
onChange={handleChange} onChange={handleChange}
selected={selectedValue} 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} {privacyDescription}
</p> </p>
</div> </div>

View File

@ -236,7 +236,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
</div> </div>
<div className="settings-item"> <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 <ListItem
narrow narrow
@ -391,7 +391,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
{canChangeSensitive && ( {canChangeSensitive && (
<div className="settings-item fluid-container"> <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')} {oldLang('lng_settings_sensitive_title')}
</h4> </h4>
<Checkbox <Checkbox
@ -419,7 +419,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
{canDisplayAutoarchiveSetting && ( {canDisplayAutoarchiveSetting && (
<div className="settings-item"> <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')} {oldLang('NewChatsFromNonContacts')}
</h4> </h4>
<Checkbox <Checkbox
@ -432,7 +432,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
)} )}
<div className="settings-item"> <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')} {oldLang('lng_settings_window_system')}
</h4> </h4>
<Checkbox <Checkbox
@ -443,7 +443,7 @@ const SettingsPrivacy: FC<OwnProps & StateProps> = ({
</div> </div>
<div className="settings-item"> <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')} {lang('DeleteMyAccount')}
</h4> </h4>
<ListItem <ListItem

View File

@ -348,7 +348,7 @@ function PrivacySubsection({
return ( return (
<> <>
<div className="settings-item"> <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 <RadioGroup
name={`visibility-${privacyKey}`} name={`visibility-${privacyKey}`}
options={visibilityOptions} options={visibilityOptions}
@ -356,12 +356,12 @@ function PrivacySubsection({
selected={privacy?.visibility} selected={privacy?.visibility}
/> />
{descriptionText && ( {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> </div>
{!isPremiumRequired && (primaryExceptionLists.shouldShowAllowed || primaryExceptionLists.shouldShowDenied) && ( {!isPremiumRequired && (primaryExceptionLists.shouldShowAllowed || primaryExceptionLists.shouldShowDenied) && (
<div className="settings-item"> <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')} {oldLang('PrivacyExceptions')}
</h4> </h4>
{primaryExceptionLists.shouldShowAllowed && ( {primaryExceptionLists.shouldShowAllowed && (

View File

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

View File

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

View File

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

View File

@ -602,7 +602,7 @@ function MiddleColumn({
/> />
)} )}
{isPinnedMessageList && canUnpin && ( {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 <Button
size="tiny" size="tiny"
fluid fluid
@ -616,7 +616,7 @@ function MiddleColumn({
</div> </div>
)} )}
{canShowOpenChatButton && ( {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 <Button
size="tiny" size="tiny"
fluid fluid
@ -640,7 +640,7 @@ function MiddleColumn({
{( {(
isMobile && (renderingCanSubscribe || (renderingShouldJoinToSend && !renderingShouldSendJoinRequest)) 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 <Button
size="tiny" size="tiny"
fluid fluid
@ -653,7 +653,7 @@ function MiddleColumn({
</div> </div>
)} )}
{isMobile && renderingShouldSendJoinRequest && ( {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 <Button
size="tiny" size="tiny"
fluid fluid
@ -666,7 +666,7 @@ function MiddleColumn({
</div> </div>
)} )}
{isMobile && renderingCanStartBot && ( {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 <Button
size="tiny" size="tiny"
fluid fluid
@ -679,7 +679,7 @@ function MiddleColumn({
</div> </div>
)} )}
{isMobile && renderingCanRestartBot && ( {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 <Button
size="tiny" size="tiny"
fluid fluid
@ -692,7 +692,7 @@ function MiddleColumn({
</div> </div>
)} )}
{isMobile && renderingCanUnblock && ( {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 <Button
size="tiny" size="tiny"
fluid fluid

View File

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

View File

@ -532,7 +532,7 @@ const AttachmentModal: FC<OwnProps & StateProps> = ({
} }
return ( 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}> <Button round color="translucent" size="smaller" ariaLabel="Cancel attachments" onClick={onClear}>
<Icon name="close" /> <Icon name="close" />
</Button> </Button>

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -170,7 +170,7 @@ const StarPaymentModal = ({
onClose={closeStarsPaymentModal} onClose={closeStarsPaymentModal}
> >
<BalanceBlock balance={starsBalanceState?.balance} className={styles.modalBalance} /> <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 ? ( {paidMediaMessage ? (
<PaidMediaThumb media={paidMediaMessage.content.paidMedia!.extendedMedia} /> <PaidMediaThumb media={paidMediaMessage.content.paidMedia!.extendedMedia} />
) : inviteCustomPeer ? ( ) : inviteCustomPeer ? (

View File

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

View File

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

View File

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

View File

@ -26,11 +26,17 @@
} }
.avatar { .avatar {
--_gradient-rotation: 90deg;
z-index: 1; z-index: 1;
:dir(rtl) & {
--_gradient-rotation: -90deg;
}
&:not(:first-child):before { &:not(:first-child):before {
mask-composite: exclude; 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) { &: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 { selectIsForumPanelOpen, selectPerformanceSettingsValue, selectTabState } from '../../global/selectors';
import { animateClosing, animateOpening, ANIMATION_DURATION } from './helpers/ribbonAnimation'; import { animateClosing, animateOpening, ANIMATION_DURATION } from './helpers/ribbonAnimation';
import useOldLang from '../../hooks/useOldLang'; import useLang from '../../hooks/useLang';
import useShowTransition from '../../hooks/useShowTransition'; import useShowTransition from '../../hooks/useShowTransition';
import useStoryPreloader from './hooks/useStoryPreloader'; import useStoryPreloader from './hooks/useStoryPreloader';
@ -50,7 +50,7 @@ function StoryToggler({
}: OwnProps & StateProps) { }: OwnProps & StateProps) {
const { toggleStoryRibbon } = getActions(); const { toggleStoryRibbon } = getActions();
const lang = useOldLang(); const lang = useLang();
const peers = useMemo(() => { const peers = useMemo(() => {
if (orderedPeerIds.length === 1) { if (orderedPeerIds.length === 1) {
@ -117,7 +117,7 @@ function StoryToggler({
type="button" type="button"
id="StoryToggler" id="StoryToggler"
className={styles.root} className={styles.root}
aria-label={lang('Chat.Context.Peer.OpenStory')} aria-label={lang('AriaStoryTogglerOpen')}
onClick={() => toggleStoryRibbon({ isShown: true, isArchived })} onClick={() => toggleStoryRibbon({ isShown: true, isArchived })}
dir={lang.isRtl ? 'rtl' : undefined} dir={lang.isRtl ? 'rtl' : undefined}
> >

View File

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

View File

@ -16,8 +16,8 @@ import { REM } from '../common/helpers/mediaDimensions';
import renderText from '../common/helpers/renderText'; import renderText from '../common/helpers/renderText';
import useCurrentOrPrev from '../../hooks/useCurrentOrPrev'; import useCurrentOrPrev from '../../hooks/useCurrentOrPrev';
import useLang from '../../hooks/useLang';
import useLastCallback from '../../hooks/useLastCallback'; import useLastCallback from '../../hooks/useLastCallback';
import useOldLang from '../../hooks/useOldLang';
import Avatar from '../common/Avatar'; import Avatar from '../common/Avatar';
import Icon from '../common/icons/Icon'; import Icon from '../common/icons/Icon';
@ -85,7 +85,7 @@ const Checkbox: FC<OwnProps> = ({
onCheck, onCheck,
onClickLabel, onClickLabel,
}) => { }) => {
const lang = useOldLang(); const lang = useLang();
const labelRef = useRef<HTMLLabelElement>(); const labelRef = useRef<HTMLLabelElement>();
const [showNested, setShowNested] = useState(false); const [showNested, setShowNested] = useState(false);
const renderingUser = useCurrentOrPrev(user, true); 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 { IS_TAURI } from '../../util/browser/globalEnvironment';
import buildClassName from '../../util/buildClassName'; import buildClassName from '../../util/buildClassName';
import useOldLang from '../../hooks/useOldLang'; import useLang from '../../hooks/useLang';
type OwnProps = { type OwnProps = {
ref?: ElementRef<HTMLInputElement>; ref?: ElementRef<HTMLInputElement>;
@ -56,7 +56,7 @@ const InputText: FC<OwnProps> = ({
onBlur, onBlur,
onPaste, onPaste,
}) => { }) => {
const lang = useOldLang(); const lang = useLang();
const labelText = error || success || label; const labelText = error || success || label;
const fullClassName = buildClassName( const fullClassName = buildClassName(
'input-group', 'input-group',

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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